summaryrefslogtreecommitdiff
path: root/lib/tremor
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-02-14 12:21:33 +1100
committerjacqueline <me@jacqueline.id.au>2024-02-14 12:21:33 +1100
commit7ec0ff2589ffd5774e78f9e6b436ea55be45deb1 (patch)
tree4bc335bf6474bff2babbcbd4690231320b52520f /lib/tremor
parentb31bc07555fdd862181d8d6ed551163cea89bc62 (diff)
downloadtangara-fw-7ec0ff2589ffd5774e78f9e6b436ea55be45deb1.tar.gz
Switch to the lowmem tremor branch
in addition to using slightly less memory, this branch also doesn't seem to have the same issues with `-O2` builds that the main branch has.
Diffstat (limited to 'lib/tremor')
-rw-r--r--lib/tremor/CMakeLists.txt10
-rw-r--r--lib/tremor/Makefile.am31
-rw-r--r--lib/tremor/TODO2
-rw-r--r--lib/tremor/Version_script.in1
-rw-r--r--lib/tremor/asm_arm.h58
-rwxr-xr-xlib/tremor/autogen.sh89
-rw-r--r--lib/tremor/backends.h131
-rw-r--r--lib/tremor/bitwise.c675
-rw-r--r--lib/tremor/block.c497
-rw-r--r--lib/tremor/block.h24
-rw-r--r--lib/tremor/codebook.c922
-rw-r--r--lib/tremor/codebook.h106
-rw-r--r--lib/tremor/codec_internal.h191
-rw-r--r--lib/tremor/config_types.h13
-rw-r--r--lib/tremor/configure.in37
-rw-r--r--lib/tremor/dsp.c298
-rw-r--r--lib/tremor/floor0.c346
-rw-r--r--lib/tremor/floor1.c392
-rw-r--r--lib/tremor/floor_lookup.c92
-rw-r--r--lib/tremor/framing.c1117
-rw-r--r--lib/tremor/info.c271
-rw-r--r--lib/tremor/iseeking_example.c265
-rw-r--r--lib/tremor/ivorbiscodec.h112
-rw-r--r--lib/tremor/ivorbisfile.h103
-rw-r--r--lib/tremor/ivorbisfile_example.c13
-rw-r--r--lib/tremor/lsp_lookup.h36
-rw-r--r--lib/tremor/mapping0.c277
-rw-r--r--lib/tremor/mdct.c704
-rw-r--r--lib/tremor/mdct.h19
-rw-r--r--lib/tremor/mdct_lookup.h10
-rw-r--r--lib/tremor/misc.c208
-rw-r--r--lib/tremor/misc.h148
-rw-r--r--lib/tremor/os.h8
-rw-r--r--lib/tremor/os_types.h42
-rw-r--r--lib/tremor/registry.c50
-rw-r--r--lib/tremor/registry.h40
-rw-r--r--lib/tremor/res012.c467
-rw-r--r--lib/tremor/sharedbook.c447
-rw-r--r--lib/tremor/synthesis.c131
-rw-r--r--lib/tremor/tremor_ogg.h206
-rw-r--r--lib/tremor/vorbisfile.c2279
-rw-r--r--lib/tremor/vorbisidec.pc.in4
-rw-r--r--lib/tremor/win32/VS2005/libogg.vsprops19
-rw-r--r--lib/tremor/win32/VS2005/libtremor/libtremor.vcproj865
-rw-r--r--lib/tremor/win32/VS2008/libogg.vsprops19
-rw-r--r--lib/tremor/win32/VS2008/libtremor/libtremor.vcproj865
-rw-r--r--lib/tremor/window.c83
-rw-r--r--lib/tremor/window.h27
-rw-r--r--lib/tremor/window_lookup.h25
49 files changed, 5676 insertions, 7099 deletions
diff --git a/lib/tremor/CMakeLists.txt b/lib/tremor/CMakeLists.txt
index 1000fe5f..e44f9084 100644
--- a/lib/tremor/CMakeLists.txt
+++ b/lib/tremor/CMakeLists.txt
@@ -2,9 +2,7 @@
#
# SPDX-License-Identifier: GPL-3.0-only
idf_component_register(
- SRCS block.c codebook.c floor0.c floor1.c info.c mapping0.c mdct.c registry.c
- res012.c sharedbook.c synthesis.c vorbisfile.c window.c
- INCLUDE_DIRS "."
- REQUIRES "ogg")
-
-target_compile_options("${COMPONENT_LIB}" PRIVATE -Og)
+ SRCS bitwise.c codebook.c dsp.c floor0.c floor1.c floor_lookup.c framing.c
+ info.c mapping0.c mdct.c misc.c res012.c vorbisfile.c
+ INCLUDE_DIRS ".")
+target_compile_options("${COMPONENT_LIB}" PRIVATE -Wno-error=misleading-indentation -Wno-error=maybe-uninitialized -Wno-error=char-subscripts -Wno-error=unused-label)
diff --git a/lib/tremor/Makefile.am b/lib/tremor/Makefile.am
index 0a4bb2c3..1d18b1a7 100644
--- a/lib/tremor/Makefile.am
+++ b/lib/tremor/Makefile.am
@@ -1,50 +1,43 @@
AUTOMAKE_OPTIONS = foreign
-INCLUDES = -I./ @OGG_CFLAGS@
+INCLUDES = -I./
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = vorbisidec.pc
lib_LTLIBRARIES = libvorbisidec.la
-libvorbisidec_la_SOURCES = mdct.c block.c window.c \
- synthesis.c info.c \
+libvorbisidec_la_SOURCES = mdct.c dsp.c info.c misc.c \
floor1.c floor0.c vorbisfile.c \
- res012.c mapping0.c registry.c codebook.c \
- sharedbook.c \
+ res012.c mapping0.c codebook.c \
+ framing.c bitwise.c \
codebook.h misc.h mdct_lookup.h\
- os.h mdct.h block.h ivorbisfile.h lsp_lookup.h\
- registry.h window.h window_lookup.h\
- codec_internal.h backends.h \
+ os.h mdct.h ivorbisfile.h lsp_lookup.h\
+ window_lookup.h floor_lookup.c \
+ codec_internal.h ogg.h \
asm_arm.h ivorbiscodec.h
libvorbisidec_la_LDFLAGS = -version-info @V_LIB_CURRENT@:@V_LIB_REVISION@:@V_LIB_AGE@
-libvorbisidec_la_LIBADD = @OGG_LIBS@
-EXTRA_PROGRAMS = ivorbisfile_example iseeking_example
+EXTRA_PROGRAMS = ivorbisfile_example
CLEANFILES = $(EXTRA_PROGRAMS) $(lib_LTLIBRARIES)
ivorbisfile_example_SOURCES = ivorbisfile_example.c
ivorbisfile_example_LDFLAGS = -static
-ivorbisfile_example_LDADD = libvorbisidec.la @OGG_LIBS@
-
-iseeking_example_SOURCES = iseeking_example.c
-iseeking_example_LDFLAGS = -static
-iseeking_example_LDADD = libvorbisidec.la @OGG_LIBS@
+ivorbisfile_example_LDADD = libvorbisidec.la
includedir = $(prefix)/include/tremor
-include_HEADERS = ivorbiscodec.h ivorbisfile.h config_types.h
+include_HEADERS = ivorbiscodec.h ivorbisfile.h ogg.h os_types.h config_types.h
EXTRA_DIST = vorbisidec.pc.in \
- $(srcdir)/doc/*.html $(srcdir)/win32/VS*/libtremor/*.vcproj
+ $(srcdir)/doc/*.html
example:
-ln -fs . vorbis
$(MAKE) ivorbisfile_example
- $(MAKE) iseeking_example
debug:
- $(MAKE) all CFLAGS="@DEBUG@"
+ $(MAKE) all CFLAGS="@DEBUG@"
profile:
$(MAKE) all CFLAGS="@PROFILE@"
diff --git a/lib/tremor/TODO b/lib/tremor/TODO
new file mode 100644
index 00000000..0e542a37
--- /dev/null
+++ b/lib/tremor/TODO
@@ -0,0 +1,2 @@
+Add explicit 64 bit integer support rather than relying on compiler
+Roll in optional use of bounded heap memory manager
diff --git a/lib/tremor/Version_script.in b/lib/tremor/Version_script.in
index cf05203c..85d76539 100644
--- a/lib/tremor/Version_script.in
+++ b/lib/tremor/Version_script.in
@@ -51,7 +51,6 @@
vorbis_synthesis_init;
vorbis_synthesis_restart;
vorbis_synthesis;
- vorbis_synthesis_trackonly;
vorbis_synthesis_blockin;
vorbis_synthesis_pcmout;
vorbis_synthesis_read;
diff --git a/lib/tremor/asm_arm.h b/lib/tremor/asm_arm.h
index c3bda005..ac2b6899 100644
--- a/lib/tremor/asm_arm.h
+++ b/lib/tremor/asm_arm.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -20,7 +20,7 @@
#if !defined(_V_WIDE_MATH) && !defined(_LOW_ACCURACY_)
#define _V_WIDE_MATH
-static inline ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
+static inline tremor_ogg_int32_t MULT32(tremor_ogg_int32_t x, tremor_ogg_int32_t y) {
int lo,hi;
asm volatile("smull\t%0, %1, %2, %3"
: "=&r"(lo),"=&r"(hi)
@@ -29,11 +29,11 @@ static inline ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
return(hi);
}
-static inline ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
+static inline tremor_ogg_int32_t MULT31(tremor_ogg_int32_t x, tremor_ogg_int32_t y) {
return MULT32(x,y)<<1;
}
-static inline ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
+static inline tremor_ogg_int32_t MULT31_SHIFT15(tremor_ogg_int32_t x, tremor_ogg_int32_t y) {
int lo,hi;
asm volatile("smull %0, %1, %2, %3\n\t"
"movs %0, %0, lsr #15\n\t"
@@ -46,9 +46,9 @@ static inline ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
#define MB() asm volatile ("" : : : "memory")
-static inline void XPROD32(ogg_int32_t a, ogg_int32_t b,
- ogg_int32_t t, ogg_int32_t v,
- ogg_int32_t *x, ogg_int32_t *y)
+static inline void XPROD32(tremor_ogg_int32_t a, tremor_ogg_int32_t b,
+ tremor_ogg_int32_t t, tremor_ogg_int32_t v,
+ tremor_ogg_int32_t *x, tremor_ogg_int32_t *y)
{
int x1, y1, l;
asm( "smull %0, %1, %4, %6\n\t"
@@ -64,9 +64,9 @@ static inline void XPROD32(ogg_int32_t a, ogg_int32_t b,
*y = y1;
}
-static inline void XPROD31(ogg_int32_t a, ogg_int32_t b,
- ogg_int32_t t, ogg_int32_t v,
- ogg_int32_t *x, ogg_int32_t *y)
+static inline void XPROD31(tremor_ogg_int32_t a, tremor_ogg_int32_t b,
+ tremor_ogg_int32_t t, tremor_ogg_int32_t v,
+ tremor_ogg_int32_t *x, tremor_ogg_int32_t *y)
{
int x1, y1, l;
asm( "smull %0, %1, %4, %6\n\t"
@@ -82,9 +82,9 @@ static inline void XPROD31(ogg_int32_t a, ogg_int32_t b,
*y = y1 << 1;
}
-static inline void XNPROD31(ogg_int32_t a, ogg_int32_t b,
- ogg_int32_t t, ogg_int32_t v,
- ogg_int32_t *x, ogg_int32_t *y)
+static inline void XNPROD31(tremor_ogg_int32_t a, tremor_ogg_int32_t b,
+ tremor_ogg_int32_t t, tremor_ogg_int32_t v,
+ tremor_ogg_int32_t *x, tremor_ogg_int32_t *y)
{
int x1, y1, l;
asm( "rsb %2, %4, #0\n\t"
@@ -105,7 +105,7 @@ static inline void XNPROD31(ogg_int32_t a, ogg_int32_t b,
#ifndef _V_CLIP_MATH
#define _V_CLIP_MATH
-static inline ogg_int32_t CLIP_TO_15(ogg_int32_t x) {
+static inline tremor_ogg_int32_t CLIP_TO_15(tremor_ogg_int32_t x) {
int tmp;
asm volatile("subs %1, %0, #32768\n\t"
"movpl %0, #0x7f00\n\t"
@@ -123,18 +123,17 @@ static inline ogg_int32_t CLIP_TO_15(ogg_int32_t x) {
#ifndef _V_LSP_MATH_ASM
#define _V_LSP_MATH_ASM
-static inline void lsp_loop_asm(ogg_uint32_t *qip,ogg_uint32_t *pip,
- ogg_int32_t *qexpp,
- ogg_int32_t *ilsp,ogg_int32_t wi,
- ogg_int32_t m){
+static inline void lsp_loop_asm(tremor_ogg_uint32_t *qip,tremor_ogg_uint32_t *pip,
+ tremor_ogg_int32_t *qexpp,
+ tremor_ogg_int32_t *ilsp,tremor_ogg_int32_t wi,
+ tremor_ogg_int32_t m){
- ogg_uint32_t qi=*qip,pi=*pip;
- ogg_int32_t qexp=*qexpp;
+ tremor_ogg_uint32_t qi=*qip,pi=*pip;
+ tremor_ogg_int32_t qexp=*qexpp;
asm("mov r0,%3;"
- "movs r1,%5,asr#1;"
+ "mov r1,%5,asr#1;"
"add r0,r0,r1,lsl#3;"
- "beq 2f;\n"
"1:"
"ldmdb r0!,{r1,r3};"
@@ -157,10 +156,9 @@ static inline void lsp_loop_asm(ogg_uint32_t *qip,ogg_uint32_t *pip,
"cmp r0,%3;\n"
"bhi 1b;\n"
- "2:"
// odd filter assymetry
"ands r0,%5,#1;\n"
- "beq 3f;\n"
+ "beq 2f;\n"
"add r0,%3,%5,lsl#2;\n"
"ldr r1,[r0,#-4];\n"
@@ -172,7 +170,7 @@ static inline void lsp_loop_asm(ogg_uint32_t *qip,ogg_uint32_t *pip,
"umull %1,r3,r0,%1;\n" //pi*=labs(ilsp[j+1]-wi)
"cmn r2,r3;\n" // shift down 16?
- "beq 3f;\n"
+ "beq 2f;\n"
"add %2,%2,#16;\n"
"mov %0,%0,lsr #16;\n"
"orr %0,%0,r2,lsl #16;\n"
@@ -186,7 +184,7 @@ static inline void lsp_loop_asm(ogg_uint32_t *qip,ogg_uint32_t *pip,
//}
/* normalize to max 16 sig figs */
- "3:"
+ "2:"
"mov r2,#0;"
"orr r1,%0,%1;"
"tst r1,#0xff000000;"
@@ -216,10 +214,10 @@ static inline void lsp_loop_asm(ogg_uint32_t *qip,ogg_uint32_t *pip,
*qexpp=qexp;
}
-static inline void lsp_norm_asm(ogg_uint32_t *qip,ogg_int32_t *qexpp){
+static inline void lsp_norm_asm(tremor_ogg_uint32_t *qip,tremor_ogg_int32_t *qexpp){
- ogg_uint32_t qi=*qip;
- ogg_int32_t qexp=*qexpp;
+ tremor_ogg_uint32_t qi=*qip;
+ tremor_ogg_int32_t qexp=*qexpp;
asm("tst %0,#0x0000ff00;"
"moveq %0,%0,lsl #8;"
diff --git a/lib/tremor/autogen.sh b/lib/tremor/autogen.sh
index 73c8fca8..e2e6f6b9 100755
--- a/lib/tremor/autogen.sh
+++ b/lib/tremor/autogen.sh
@@ -2,16 +2,14 @@
# Run this to set up the build system: configure, makefiles, etc.
# (based on the version in enlightenment's cvs)
-package="vorbisdec"
+package="vorbisidec"
-olddir=`pwd`
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
cd "$srcdir"
DIE=0
-echo "checking for autoconf... "
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $package."
@@ -20,72 +18,16 @@ echo "checking for autoconf... "
DIE=1
}
-VERSIONGREP="sed -e s/.*[^0-9\.]\([0-9]\.[0-9]\).*/\1/"
-VERSIONMKINT="sed -e s/[^0-9]//"
-
-# do we need automake?
-if test -r Makefile.am; then
- AM_OPTIONS=`fgrep AUTOMAKE_OPTIONS Makefile.am`
- AM_NEEDED=`echo $AM_OPTIONS | $VERSIONGREP`
- if test x"$AM_NEEDED" = "x$AM_OPTIONS"; then
- AM_NEEDED=""
- fi
- if test -z $AM_NEEDED; then
- echo -n "checking for automake... "
- AUTOMAKE=automake
- ACLOCAL=aclocal
- if ($AUTOMAKE --version < /dev/null > /dev/null 2>&1); then
- echo "yes"
- else
- echo "no"
- AUTOMAKE=
- fi
- else
- echo -n "checking for automake $AM_NEEDED or later... "
- for am in automake-$AM_NEEDED automake$AM_NEEDED automake; do
- ($am --version < /dev/null > /dev/null 2>&1) || continue
- ver=`$am --version < /dev/null | head -n 1 | $VERSIONGREP | $VERSIONMKINT`
- verneeded=`echo $AM_NEEDED | $VERSIONMKINT`
- if test $ver -ge $verneeded; then
- AUTOMAKE=$am
- echo $AUTOMAKE
- break
- fi
- done
- test -z $AUTOMAKE && echo "no"
- echo -n "checking for aclocal $AM_NEEDED or later... "
- for ac in aclocal-$AM_NEEDED aclocal$AM_NEEDED aclocal; do
- ($ac --version < /dev/null > /dev/null 2>&1) || continue
- ver=`$ac --version < /dev/null | head -n 1 | $VERSIONGREP | $VERSIONMKINT`
- verneeded=`echo $AM_NEEDED | $VERSIONMKINT`
- if test $ver -ge $verneeded; then
- ACLOCAL=$ac
- echo $ACLOCAL
- break
- fi
- done
- test -z $ACLOCAL && echo "no"
- fi
- test -z $AUTOMAKE || test -z $ACLOCAL && {
+(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have automake installed to compile $package."
- echo "Download the appropriate package for your distribution,"
- echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
- exit 1
- }
-fi
+ echo "Download the appropriate package for your system,"
+ echo "or get the source from one of the GNU ftp sites"
+ echo "listed in http://www.gnu.org/order/ftp.html"
+ DIE=1
+}
-echo -n "checking for libtool... "
-for LIBTOOLIZE in libtoolize glibtoolize nope; do
- ($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 && break
-done
-if test x$LIBTOOLIZE = xnope; then
- echo "nope."
- LIBTOOLIZE=libtoolize
-else
- echo $LIBTOOLIZE
-fi
-($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || {
+(libtool --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have libtool installed to compile $package."
echo "Download the appropriate package for your system,"
@@ -105,16 +47,15 @@ fi
echo "Generating configuration files for $package, please wait...."
-echo " $ACLOCAL $ACLOCAL_FLAGS"
-$ACLOCAL $ACLOCAL_FLAGS || exit 1
-echo " $LIBTOOLIZE --automake"
-$LIBTOOLIZE --automake || exit 1
+echo " aclocal $ACLOCAL_FLAGS"
+aclocal $ACLOCAL_FLAGS || exit 1
echo " autoheader"
autoheader || exit 1
-echo " $AUTOMAKE --add-missing $AUTOMAKE_FLAGS"
-$AUTOMAKE --add-missing $AUTOMAKE_FLAGS || exit 1
+echo " libtoolize --automake"
+libtoolize --automake || exit 1
+echo " automake --add-missing $AUTOMAKE_FLAGS"
+automake --add-missing $AUTOMAKE_FLAGS || exit 1
echo " autoconf"
autoconf || exit 1
-cd $olddir
-$srcdir/configure --enable-maintainer-mode "$@" && echo
+$srcdir/configure "$@" && echo
diff --git a/lib/tremor/backends.h b/lib/tremor/backends.h
deleted file mode 100644
index 52024219..00000000
--- a/lib/tremor/backends.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
- * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: backend and mapping structures
-
- ********************************************************************/
-
-/* this is exposed up here because we need it for static modes.
- Lookups for each backend aren't exposed because there's no reason
- to do so */
-
-#ifndef _vorbis_backend_h_
-#define _vorbis_backend_h_
-
-#include "codec_internal.h"
-
-/* this would all be simpler/shorter with templates, but.... */
-/* Transform backend generic *************************************/
-
-/* only mdct right now. Flesh it out more if we ever transcend mdct
- in the transform domain */
-
-/* Floor backend generic *****************************************/
-typedef struct{
- vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *);
- vorbis_look_floor *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
- vorbis_info_floor *);
- void (*free_info) (vorbis_info_floor *);
- void (*free_look) (vorbis_look_floor *);
- void *(*inverse1) (struct vorbis_block *,vorbis_look_floor *);
- int (*inverse2) (struct vorbis_block *,vorbis_look_floor *,
- void *buffer,ogg_int32_t *);
-} vorbis_func_floor;
-
-typedef struct{
- int order;
- long rate;
- long barkmap;
-
- int ampbits;
- int ampdB;
-
- int numbooks; /* <= 16 */
- int books[16];
-
-} vorbis_info_floor0;
-
-#define VIF_POSIT 63
-#define VIF_CLASS 16
-#define VIF_PARTS 31
-typedef struct{
- int partitions; /* 0 to 31 */
- int partitionclass[VIF_PARTS]; /* 0 to 15 */
-
- int class_dim[VIF_CLASS]; /* 1 to 8 */
- int class_subs[VIF_CLASS]; /* 0,1,2,3 (bits: 1<<n poss) */
- int class_book[VIF_CLASS]; /* subs ^ dim entries */
- int class_subbook[VIF_CLASS][8]; /* [VIF_CLASS][subs] */
-
-
- int mult; /* 1 2 3 or 4 */
- int postlist[VIF_POSIT+2]; /* first two implicit */
-
-} vorbis_info_floor1;
-
-/* Residue backend generic *****************************************/
-typedef struct{
- vorbis_info_residue *(*unpack)(vorbis_info *,oggpack_buffer *);
- vorbis_look_residue *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
- vorbis_info_residue *);
- void (*free_info) (vorbis_info_residue *);
- void (*free_look) (vorbis_look_residue *);
- int (*inverse) (struct vorbis_block *,vorbis_look_residue *,
- ogg_int32_t **,int *,int);
-} vorbis_func_residue;
-
-typedef struct vorbis_info_residue0{
-/* block-partitioned VQ coded straight residue */
- long begin;
- long end;
-
- /* first stage (lossless partitioning) */
- int grouping; /* group n vectors per partition */
- int partitions; /* possible codebooks for a partition */
- int partvals; /* partitions ^ groupbook dim */
- int groupbook; /* huffbook for partitioning */
- int secondstages[64]; /* expanded out to pointers in lookup */
- int booklist[512]; /* list of second stage books */
-} vorbis_info_residue0;
-
-/* Mapping backend generic *****************************************/
-typedef struct{
- vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *);
- vorbis_look_mapping *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
- vorbis_info_mapping *);
- void (*free_info) (vorbis_info_mapping *);
- void (*free_look) (vorbis_look_mapping *);
- int (*inverse) (struct vorbis_block *vb,vorbis_look_mapping *);
-} vorbis_func_mapping;
-
-typedef struct vorbis_info_mapping0{
- int submaps; /* <= 16 */
- int chmuxlist[256]; /* up to 256 channels in a Vorbis stream */
-
- int floorsubmap[16]; /* [mux] submap to floors */
- int residuesubmap[16]; /* [mux] submap to residue */
-
- int psy[2]; /* by blocktype; impulse/padding for short,
- transition/normal for long */
-
- int coupling_steps;
- int coupling_mag[256];
- int coupling_ang[256];
-} vorbis_info_mapping0;
-
-#endif
-
-
-
-
-
diff --git a/lib/tremor/bitwise.c b/lib/tremor/bitwise.c
new file mode 100644
index 00000000..402b6156
--- /dev/null
+++ b/lib/tremor/bitwise.c
@@ -0,0 +1,675 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: packing variable sized words into an octet stream
+
+ ********************************************************************/
+
+/* We're 'LSb' endian; if we write a word but read individual bits,
+ then we'll read the lsb first */
+
+#include <string.h>
+#include <stdlib.h>
+#include "misc.h"
+#include "tremor_ogg.h"
+
+static unsigned long mask[]=
+{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
+ 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
+ 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
+ 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
+ 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
+ 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
+ 0x3fffffff,0x7fffffff,0xffffffff };
+
+/* spans forward, skipping as many bytes as headend is negative; if
+ headend is zero, simply finds next byte. If we're up to the end
+ of the buffer, leaves headend at zero. If we've read past the end,
+ halt the decode process. */
+
+static void _span(tremor_oggpack_buffer *b){
+ while(b->headend-(b->headbit>>3)<1){
+ b->headend-=b->headbit>>3;
+ b->headbit&=0x7;
+
+ if(b->head->next){
+ b->count+=b->head->length;
+ b->head=b->head->next;
+
+ if(b->headend+b->head->length>0)
+ b->headptr=b->head->buffer->data+b->head->begin-b->headend;
+
+ b->headend+=b->head->length;
+ }else{
+ /* we've either met the end of decode, or gone past it. halt
+ only if we're past */
+ if(b->headend*8<b->headbit)
+ /* read has fallen off the end */
+ b->headend=-1;
+ break;
+ }
+ }
+}
+
+void tremor_oggpack_readinit(tremor_oggpack_buffer *b,tremor_ogg_reference *r){
+ memset(b,0,sizeof(*b));
+
+ b->tail=b->head=r;
+ b->count=0;
+ b->headptr=b->head->buffer->data+b->head->begin;
+ b->headend=b->head->length;
+ _span(b);
+}
+
+#define _lookspan() while(!end){\
+ head=head->next;\
+ if(!head) return -1;\
+ ptr=head->buffer->data + head->begin;\
+ end=head->length;\
+ }
+
+/* Read in bits without advancing the bitptr; bits <= 32 */
+long tremor_oggpack_look(tremor_oggpack_buffer *b,int bits){
+ unsigned long m=mask[bits];
+ unsigned long ret;
+
+ bits+=b->headbit;
+
+ if(bits >= b->headend<<3){
+ int end=b->headend;
+ unsigned char *ptr=b->headptr;
+ tremor_ogg_reference *head=b->head;
+
+ if(end<0)return -1;
+
+ if(bits){
+ _lookspan();
+ ret=*ptr++>>b->headbit;
+ if(bits>8){
+ --end;
+ _lookspan();
+ ret|=*ptr++<<(8-b->headbit);
+ if(bits>16){
+ --end;
+ _lookspan();
+ ret|=*ptr++<<(16-b->headbit);
+ if(bits>24){
+ --end;
+ _lookspan();
+ ret|=*ptr++<<(24-b->headbit);
+ if(bits>32 && b->headbit){
+ --end;
+ _lookspan();
+ ret|=*ptr<<(32-b->headbit);
+ }
+ }
+ }
+ }
+ }
+
+ }else{
+
+ /* make this a switch jump-table */
+ ret=b->headptr[0]>>b->headbit;
+ if(bits>8){
+ ret|=b->headptr[1]<<(8-b->headbit);
+ if(bits>16){
+ ret|=b->headptr[2]<<(16-b->headbit);
+ if(bits>24){
+ ret|=b->headptr[3]<<(24-b->headbit);
+ if(bits>32 && b->headbit)
+ ret|=b->headptr[4]<<(32-b->headbit);
+ }
+ }
+ }
+ }
+
+ ret&=m;
+ return ret;
+}
+
+/* limited to 32 at a time */
+void tremor_oggpack_adv(tremor_oggpack_buffer *b,int bits){
+ bits+=b->headbit;
+ b->headbit=bits&7;
+ b->headend-=(bits>>3);
+ b->headptr+=(bits>>3);
+ if(b->headend<1)_span(b);
+}
+
+int tremor_oggpack_eop(tremor_oggpack_buffer *b){
+ if(b->headend<0)return -1;
+ return 0;
+}
+
+/* bits <= 32 */
+long tremor_oggpack_read(tremor_oggpack_buffer *b,int bits){
+ long ret=tremor_oggpack_look(b,bits);
+ tremor_oggpack_adv(b,bits);
+ return(ret);
+}
+
+long tremor_oggpack_bytes(tremor_oggpack_buffer *b){
+ if(b->headend<0)return b->count+b->head->length;
+ return b->count + b->head->length-b->headend +
+ (b->headbit+7)/8;
+}
+
+long tremor_oggpack_bits(tremor_oggpack_buffer *b){
+ if(b->headend<0)return (b->count+b->head->length)*8;
+ return (b->count + b->head->length-b->headend)*8 +
+ b->headbit;
+}
+
+/* Self test of the bitwise routines; everything else is based on
+ them, so they damned well better be solid. */
+
+#ifdef _V_BIT_TEST
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "framing.c"
+
+static int ilog(unsigned long v){
+ int ret=0;
+ while(v){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+tremor_oggpack_buffer r;
+tremor_oggpack_buffer o;
+tremor_ogg_buffer_state *bs;
+tremor_ogg_reference *or;
+#define TESTWORDS 256
+
+void report(char *in){
+ fprintf(stderr,"%s",in);
+ exit(1);
+}
+
+int getbyte(tremor_ogg_reference *or,int position){
+ while(or && position>=or->length){
+ position-=or->length;
+ or=or->next;
+ if(or==NULL){
+ fprintf(stderr,"\n\tERROR: getbyte ran off end of buffer.\n");
+ exit(1);
+ }
+ }
+
+ if((position+or->begin)&1)
+ return (or->buffer->data[(position+or->begin)>>1])&0xff;
+ else
+ return (or->buffer->data[(position+or->begin)>>1]>>8)&0xff;
+}
+
+void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
+ long i,bitcount=0;
+ tremor_ogg_reference *or=tremor_ogg_buffer_alloc(bs,64);
+ for(i=0;i<compsize;i++)
+ or->buffer->data[i]= comp[i];
+ or->length=i;
+
+ tremor_oggpack_readinit(&r,or);
+ for(i=0;i<vals;i++){
+ unsigned long test;
+ int tbit=bits?bits:ilog(b[i]);
+ if((test=tremor_oggpack_look(&r,tbit))==0xffffffff)
+ report("out of data!\n");
+ if(test!=(b[i]&mask[tbit])){
+ fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
+ report("looked at incorrect value!\n");
+ }
+ if((test=tremor_oggpack_read(&r,tbit))==0xffffffff){
+ report("premature end of data when reading!\n");
+ }
+ if(test!=(b[i]&mask[tbit])){
+ fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
+ report("read incorrect value!\n");
+ }
+ bitcount+=tbit;
+
+ if(bitcount!=tremor_oggpack_bits(&r))
+ report("wrong number of bits while reading!\n");
+ if((bitcount+7)/8!=tremor_oggpack_bytes(&r))
+ report("wrong number of bytes while reading!\n");
+
+ }
+ if(tremor_oggpack_bytes(&r)!=(bitcount+7)/8)report("leftover bytes after read!\n");
+ tremor_ogg_buffer_release(or);
+}
+
+void _end_verify(int count){
+ int i;
+
+ /* are the proper number of bits left over? */
+ int leftover=count*8-tremor_oggpack_bits(&o);
+ if(leftover>7)
+ report("\nERROR: too many bits reported left over.\n");
+
+ /* does reading to exactly byte alignment *not* trip EOF? */
+ if(tremor_oggpack_read(&o,leftover)==-1)
+ report("\nERROR: read to but not past exact end tripped EOF.\n");
+ if(tremor_oggpack_bits(&o)!=count*8)
+ report("\nERROR: read to but not past exact end reported bad bitcount.\n");
+
+ /* does EOF trip properly after a single additional bit? */
+ if(tremor_oggpack_read(&o,1)!=-1)
+ report("\nERROR: read past exact end did not trip EOF.\n");
+ if(tremor_oggpack_bits(&o)!=count*8)
+ report("\nERROR: read past exact end reported bad bitcount.\n");
+
+ /* does EOF stay set over additional bit reads? */
+ for(i=0;i<=32;i++){
+ if(tremor_oggpack_read(&o,i)!=-1)
+ report("\nERROR: EOF did not stay set on stream.\n");
+ if(tremor_oggpack_bits(&o)!=count*8)
+ report("\nERROR: read past exact end reported bad bitcount.\n");
+ }
+}
+
+void _end_verify2(int count){
+ int i;
+
+ /* are the proper number of bits left over? */
+ int leftover=count*8-tremor_oggpack_bits(&o);
+ if(leftover>7)
+ report("\nERROR: too many bits reported left over.\n");
+
+ /* does reading to exactly byte alignment *not* trip EOF? */
+ tremor_oggpack_adv(&o,leftover);
+ if(o.headend!=0)
+ report("\nERROR: read to but not past exact end tripped EOF.\n");
+ if(tremor_oggpack_bits(&o)!=count*8)
+ report("\nERROR: read to but not past exact end reported bad bitcount.\n");
+
+ /* does EOF trip properly after a single additional bit? */
+ tremor_oggpack_adv(&o,1);
+ if(o.headend>=0)
+ report("\nERROR: read past exact end did not trip EOF.\n");
+ if(tremor_oggpack_bits(&o)!=count*8)
+ report("\nERROR: read past exact end reported bad bitcount.\n");
+
+ /* does EOF stay set over additional bit reads? */
+ for(i=0;i<=32;i++){
+ tremor_oggpack_adv(&o,i);
+ if(o.headend>=0)
+ report("\nERROR: EOF did not stay set on stream.\n");
+ if(tremor_oggpack_bits(&o)!=count*8)
+ report("\nERROR: read past exact end reported bad bitcount.\n");
+ }
+}
+
+long tremor_ogg_buffer_length(tremor_ogg_reference *or){
+ int count=0;
+ while(or){
+ count+=or->length;
+ or=or->next;
+ }
+ return count;
+}
+
+tremor_ogg_reference *tremor_ogg_buffer_extend(tremor_ogg_reference *or,long bytes){
+ if(or){
+ while(or->next){
+ or=or->next;
+ }
+ or->next=tremor_ogg_buffer_alloc(or->buffer->ptr.owner,bytes);
+ return(or->next);
+ }
+ return 0;
+}
+
+void tremor_ogg_buffer_posttruncate(tremor_ogg_reference *or,long pos){
+ /* walk to the point where we want to begin truncate */
+ while(or && pos>or->length){
+ pos-=or->length;
+ or=or->next;
+ }
+ if(or){
+ tremor_ogg_buffer_release(or->next);
+ or->next=0;
+ or->length=pos;
+ }
+}
+
+int main(void){
+ long i;
+ static unsigned long testbuffer1[]=
+ {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
+ 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
+ int test1size=43;
+
+ static unsigned long testbuffer2[]=
+ {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
+ 1233432,534,5,346435231,14436467,7869299,76326614,167548585,
+ 85525151,0,12321,1,349528352};
+ int test2size=21;
+
+ static unsigned long testbuffer3[]=
+ {1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1,
+ 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
+ int test3size=56;
+
+ static unsigned long large[]=
+ {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
+ 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
+ 85525151,0,12321,1,2146528352};
+
+ int onesize=33;
+ static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
+ 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
+ 223,4};
+
+ int twosize=6;
+ static int two[6]={61,255,255,251,231,29};
+
+ int threesize=54;
+ static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
+ 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
+ 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
+ 100,52,4,14,18,86,77,1};
+
+ int foursize=38;
+ static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
+ 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
+ 28,2,133,0,1};
+
+ int fivesize=45;
+ static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
+ 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
+ 84,75,159,2,1,0,132,192,8,0,0,18,22};
+
+ int sixsize=7;
+ static int six[7]={17,177,170,242,169,19,148};
+
+ /* Test read/write together */
+ /* Later we test against pregenerated bitstreams */
+ bs=tremor_ogg_buffer_create();
+
+ fprintf(stderr,"\nSmall preclipped packing (LSb): ");
+ cliptest(testbuffer1,test1size,0,one,onesize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nNull bit call (LSb): ");
+ cliptest(testbuffer3,test3size,0,two,twosize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nLarge preclipped packing (LSb): ");
+ cliptest(testbuffer2,test2size,0,three,threesize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
+
+ or=tremor_ogg_buffer_alloc(bs,128);
+ for(i=0;i<test2size;i++){
+ or->buffer->data[i*4] = large[i]&0xff;
+ or->buffer->data[i*4+1] = (large[i]>>8)&0xff;
+ or->buffer->data[i*4+2] = (large[i]>>16)&0xff;
+ or->buffer->data[i*4+3] = (large[i]>>24)&0xff;
+ }
+ or->length=test2size*4;
+ tremor_oggpack_readinit(&r,or);
+ for(i=0;i<test2size;i++){
+ unsigned long test;
+ if((test=tremor_oggpack_look(&r,32))==0xffffffffUL)report("out of data. failed!");
+ if(test!=large[i]){
+ fprintf(stderr,"%ld != %ld (%lx!=%lx):",test,large[i],
+ test,large[i]);
+ report("read incorrect value!\n");
+ }
+ tremor_oggpack_adv(&r,32);
+ }
+ tremor_ogg_buffer_release(or);
+ if(tremor_oggpack_bytes(&r)!=test2size*4)report("leftover bytes after read!\n");
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nSmall unclipped packing (LSb): ");
+ cliptest(testbuffer1,test1size,7,four,foursize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nLarge unclipped packing (LSb): ");
+ cliptest(testbuffer2,test2size,17,five,fivesize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
+ cliptest(testbuffer3,test3size,1,six,sixsize);
+ fprintf(stderr,"ok.");
+
+ fprintf(stderr,"\nTesting read past end (LSb): ");
+ {
+ unsigned char dda[]={0,0,0,0};
+ tremor_ogg_buffer lob={dda,8,0,{0}};
+ tremor_ogg_reference lor={&lob,0,8,0};
+
+ tremor_oggpack_readinit(&r,&lor);
+ for(i=0;i<64;i++){
+ if(tremor_oggpack_read(&r,1)<0){
+ fprintf(stderr,"failed; got -1 prematurely.\n");
+ exit(1);
+ }
+ }
+ if(tremor_oggpack_look(&r,1)!=-1 ||
+ tremor_oggpack_read(&r,1)!=-1){
+ fprintf(stderr,"failed; read past end without -1.\n");
+ exit(1);
+ }
+ }
+ {
+ unsigned char dda[]={0,0,0,0};
+ tremor_ogg_buffer lob={dda,8,0,{0}};
+ tremor_ogg_reference lor={&lob,0,8,0};
+ unsigned long test;
+
+ tremor_oggpack_readinit(&r,&lor);
+ if((test=tremor_oggpack_read(&r,30))==0xffffffffUL ||
+ (test=tremor_oggpack_read(&r,16))==0xffffffffUL){
+ fprintf(stderr,"failed 2; got -1 prematurely.\n");
+ exit(1);
+ }
+
+ if((test=tremor_oggpack_look(&r,18))==0xffffffffUL){
+ fprintf(stderr,"failed 3; got -1 prematurely.\n");
+ exit(1);
+ }
+ if((test=tremor_oggpack_look(&r,19))!=0xffffffffUL){
+ fprintf(stderr,"failed; read past end without -1.\n");
+ exit(1);
+ }
+ if((test=tremor_oggpack_look(&r,32))!=0xffffffffUL){
+ fprintf(stderr,"failed; read past end without -1.\n");
+ exit(1);
+ }
+ }
+ fprintf(stderr,"ok.\n");
+
+ /* now the scary shit: randomized testing */
+
+ for(i=0;i<10000;i++){
+ long j,count=0,count2=0,bitcount=0;
+ unsigned long values[TESTWORDS];
+ int len[TESTWORDS];
+ unsigned char flat[4*TESTWORDS]; /* max possible needed size */
+
+ memset(flat,0,sizeof(flat));
+ fprintf(stderr,"\rRandomized testing (LSb)... (%ld) ",10000-i);
+
+ /* generate a list of words and lengths */
+ /* write the required number of bits out to packbuffer */
+ {
+ long word=0;
+ long bit=0;
+ int k;
+
+ for(j=0;j<TESTWORDS;j++){
+ values[j]=rand();
+ len[j]=(rand()%33);
+
+ for(k=0;k<len[j];k++){
+ flat[word] |= ((values[j]>>k)&0x1)<<bit;
+ bit++;
+ bitcount++;
+ if(bit>7){
+ bit=0;
+ word++;
+ }
+ }
+ }
+ }
+ count2=(bitcount+7)>>3;
+
+ /* construct random-length buffer chain from flat vector; random
+ byte starting offset within the length of the vector */
+ {
+ tremor_ogg_reference *or=NULL,*orl=NULL;
+ long pos=0;
+
+ /* build buffer chain */
+ while(count2){
+ int ilen=(rand()%32),k;
+ int ibegin=(rand()%32);
+
+
+ if(ilen>count2)ilen=count2;
+
+ if(or)
+ orl=tremor_ogg_buffer_extend(orl,64);
+ else
+ or=orl=tremor_ogg_buffer_alloc(bs,64);
+
+ orl->length=ilen;
+ orl->begin=ibegin;
+
+ for(k=0;k<ilen;k++)
+ orl->buffer->data[ibegin++]= flat[pos++];
+
+ count2-=ilen;
+ }
+
+ if(tremor_ogg_buffer_length(or)!=(bitcount+7)/8){
+ fprintf(stderr,"\nERROR: buffer length incorrect after build.\n");
+ exit(1);
+ }
+
+
+ {
+ int begin=0; //=(rand()%TESTWORDS);
+ int ilen=(rand()%(TESTWORDS-begin));
+ int bitoffset,bitcount=0;
+ unsigned long temp;
+
+ for(j=0;j<begin;j++)
+ bitcount+=len[j];
+ or=tremor_ogg_buffer_pretruncate(or,bitcount/8);
+ bitoffset=bitcount%=8;
+ for(;j<begin+ilen;j++)
+ bitcount+=len[j];
+ tremor_ogg_buffer_posttruncate(or,((bitcount+7)/8));
+
+ if((count=tremor_ogg_buffer_length(or))!=(bitcount+7)/8){
+ fprintf(stderr,"\nERROR: buffer length incorrect after truncate.\n");
+ exit(1);
+ }
+
+ tremor_oggpack_readinit(&o,or);
+
+ /* verify bit count */
+ if(tremor_oggpack_bits(&o)!=0){
+ fprintf(stderr,"\nERROR: Read bitcounter not zero!\n");
+ exit(1);
+ }
+ if(tremor_oggpack_bytes(&o)!=0){
+ fprintf(stderr,"\nERROR: Read bytecounter not zero!\n");
+ exit(1);
+ }
+
+ bitcount=bitoffset;
+ tremor_oggpack_read(&o,bitoffset);
+
+ /* read and compare to original list */
+ for(j=begin;j<begin+ilen;j++){
+ temp=tremor_oggpack_read(&o,len[j]);
+ if(temp==0xffffffffUL){
+ fprintf(stderr,"\nERROR: End of stream too soon! word: %ld,%d\n",
+ j-begin,ilen);
+ exit(1);
+ }
+ if(temp!=(values[j]&mask[len[j]])){
+ fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %ld, len %d\n"
+,
+ values[j]&mask[len[j]],temp,j-begin,len[j]);
+ exit(1);
+ }
+ bitcount+=len[j];
+ if(tremor_oggpack_bits(&o)!=bitcount){
+ fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
+ bitcount,tremor_oggpack_bits(&o));
+ exit(1);
+ }
+ if(tremor_oggpack_bytes(&o)!=(bitcount+7)/8){
+ fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
+ (bitcount+7)/8,tremor_oggpack_bytes(&o));
+ exit(1);
+ }
+
+ }
+ _end_verify(count);
+
+ /* look/adv version */
+ tremor_oggpack_readinit(&o,or);
+ bitcount=bitoffset;
+ tremor_oggpack_adv(&o,bitoffset);
+
+ /* read and compare to original list */
+ for(j=begin;j<begin+ilen;j++){
+ temp=tremor_oggpack_look(&o,len[j]);
+
+ if(temp==0xffffffffUL){
+ fprintf(stderr,"\nERROR: End of stream too soon! word: %ld\n",
+ j-begin);
+ exit(1);
+ }
+ if(temp!=(values[j]&mask[len[j]])){
+ fprintf(stderr,"\nERROR: Incorrect look %lx != %lx, word %ld, len %d\n"
+,
+ values[j]&mask[len[j]],temp,j-begin,len[j]);
+ exit(1);
+ }
+ tremor_oggpack_adv(&o,len[j]);
+ bitcount+=len[j];
+ if(tremor_oggpack_bits(&o)!=bitcount){
+ fprintf(stderr,"\nERROR: Look/Adv bitcounter %d != %ld!\n",
+ bitcount,tremor_oggpack_bits(&o));
+ exit(1);
+ }
+ if(tremor_oggpack_bytes(&o)!=(bitcount+7)/8){
+ fprintf(stderr,"\nERROR: Look/Adv bytecounter %d != %ld!\n",
+ (bitcount+7)/8,tremor_oggpack_bytes(&o));
+ exit(1);
+ }
+
+ }
+ _end_verify2(count);
+
+ }
+ tremor_ogg_buffer_release(or);
+ }
+ }
+ fprintf(stderr,"\rRandomized testing (LSb)... ok. \n");
+
+ return(0);
+}
+#endif
diff --git a/lib/tremor/block.c b/lib/tremor/block.c
deleted file mode 100644
index 666bc51a..00000000
--- a/lib/tremor/block.c
+++ /dev/null
@@ -1,497 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
- * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: PCM data vector blocking, windowing and dis/reassembly
-
- ********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ogg/ogg.h>
-#include "ivorbiscodec.h"
-#include "codec_internal.h"
-
-#include "window.h"
-#include "registry.h"
-#include "misc.h"
-
-static int ilog(unsigned int v){
- int ret=0;
- if(v)--v;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
-}
-
-/* pcm accumulator examples (not exhaustive):
-
- <-------------- lW ---------------->
- <--------------- W ---------------->
-: .....|..... _______________ |
-: .''' | '''_--- | |\ |
-:.....''' |_____--- '''......| | \_______|
-:.................|__________________|_______|__|______|
- |<------ Sl ------>| > Sr < |endW
- |beginSl |endSl | |endSr
- |beginW |endlW |beginSr
-
-
- |< lW >|
- <--------------- W ---------------->
- | | .. ______________ |
- | | ' `/ | ---_ |
- |___.'___/`. | ---_____|
- |_______|__|_______|_________________|
- | >|Sl|< |<------ Sr ----->|endW
- | | |endSl |beginSr |endSr
- |beginW | |endlW
- mult[0] |beginSl mult[n]
-
- <-------------- lW ----------------->
- |<--W-->|
-: .............. ___ | |
-: .''' |`/ \ | |
-:.....''' |/`....\|...|
-:.........................|___|___|___|
- |Sl |Sr |endW
- | | |endSr
- | |beginSr
- | |endSl
- |beginSl
- |beginW
-*/
-
-/* block abstraction setup *********************************************/
-
-#ifndef WORD_ALIGN
-#define WORD_ALIGN 8
-#endif
-
-int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
- memset(vb,0,sizeof(*vb));
- vb->vd=v;
- vb->localalloc=0;
- vb->localstore=NULL;
-
- return(0);
-}
-
-void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
- bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
- if(bytes+vb->localtop>vb->localalloc){
- /* can't just _ogg_realloc... there are outstanding pointers */
- if(vb->localstore){
- struct alloc_chain *link=(struct alloc_chain *)_ogg_malloc(sizeof(*link));
- vb->totaluse+=vb->localtop;
- link->next=vb->reap;
- link->ptr=vb->localstore;
- vb->reap=link;
- }
- /* highly conservative */
- vb->localalloc=bytes;
- vb->localstore=_ogg_malloc(vb->localalloc);
- vb->localtop=0;
- }
- {
- void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
- vb->localtop+=bytes;
- return ret;
- }
-}
-
-/* reap the chain, pull the ripcord */
-void _vorbis_block_ripcord(vorbis_block *vb){
- /* reap the chain */
- struct alloc_chain *reap=vb->reap;
- while(reap){
- struct alloc_chain *next=reap->next;
- _ogg_free(reap->ptr);
- memset(reap,0,sizeof(*reap));
- _ogg_free(reap);
- reap=next;
- }
- /* consolidate storage */
- if(vb->totaluse){
- vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
- vb->localalloc+=vb->totaluse;
- vb->totaluse=0;
- }
-
- /* pull the ripcord */
- vb->localtop=0;
- vb->reap=NULL;
-}
-
-int vorbis_block_clear(vorbis_block *vb){
- _vorbis_block_ripcord(vb);
- if(vb->localstore)_ogg_free(vb->localstore);
-
- memset(vb,0,sizeof(*vb));
- return(0);
-}
-
-static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
- int i;
- codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- private_state *b=NULL;
-
- if(ci==NULL) return 1;
-
- memset(v,0,sizeof(*v));
- b=(private_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b)));
-
- v->vi=vi;
- b->modebits=ilog(ci->modes);
-
- /* Vorbis I uses only window type 0 */
- b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2);
- b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2);
-
- /* finish the codebooks */
- if(!ci->fullbooks){
- ci->fullbooks=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
- for(i=0;i<ci->books;i++){
- if(ci->book_param[i]==NULL)
- goto abort_books;
- if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
- goto abort_books;
- /* decode codebooks are now standalone after init */
- vorbis_staticbook_destroy(ci->book_param[i]);
- ci->book_param[i]=NULL;
- }
- }
-
- v->pcm_storage=ci->blocksizes[1];
- v->pcm=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcm));
- v->pcmret=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcmret));
- for(i=0;i<vi->channels;i++)
- v->pcm[i]=(ogg_int32_t *)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
-
- /* all 1 (large block) or 0 (small block) */
- /* explicitly set for the sake of clarity */
- v->lW=0; /* previous window size */
- v->W=0; /* current window size */
-
- /* initialize all the mapping/backend lookups */
- b->mode=(vorbis_look_mapping **)_ogg_calloc(ci->modes,sizeof(*b->mode));
- for(i=0;i<ci->modes;i++){
- int mapnum=ci->mode_param[i]->mapping;
- int maptype=ci->map_type[mapnum];
- b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
- ci->map_param[mapnum]);
- }
- return 0;
-abort_books:
- for(i=0;i<ci->books;i++){
- if(ci->book_param[i]!=NULL){
- vorbis_staticbook_destroy(ci->book_param[i]);
- ci->book_param[i]=NULL;
- }
- }
- vorbis_dsp_clear(v);
- return -1;
-}
-
-int vorbis_synthesis_restart(vorbis_dsp_state *v){
- vorbis_info *vi=v->vi;
- codec_setup_info *ci;
-
- if(!v->backend_state)return -1;
- if(!vi)return -1;
- ci=vi->codec_setup;
- if(!ci)return -1;
-
- v->centerW=ci->blocksizes[1]/2;
- v->pcm_current=v->centerW;
-
- v->pcm_returned=-1;
- v->granulepos=-1;
- v->sequence=-1;
- ((private_state *)(v->backend_state))->sample_count=-1;
-
- return(0);
-}
-
-int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
- if(_vds_init(v,vi))return 1;
- vorbis_synthesis_restart(v);
-
- return 0;
-}
-
-void vorbis_dsp_clear(vorbis_dsp_state *v){
- int i;
- if(v){
- vorbis_info *vi=v->vi;
- codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL);
- private_state *b=(private_state *)v->backend_state;
-
- if(v->pcm){
- for(i=0;i<vi->channels;i++)
- if(v->pcm[i])_ogg_free(v->pcm[i]);
- _ogg_free(v->pcm);
- if(v->pcmret)_ogg_free(v->pcmret);
- }
-
- /* free mode lookups; these are actually vorbis_look_mapping structs */
- if(ci){
- for(i=0;i<ci->modes;i++){
- int mapnum=ci->mode_param[i]->mapping;
- int maptype=ci->map_type[mapnum];
- if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
- }
- }
-
- if(b){
- if(b->mode)_ogg_free(b->mode);
- _ogg_free(b);
- }
-
- memset(v,0,sizeof(*v));
- }
-}
-
-/* Unlike in analysis, the window is only partially applied for each
- block. The time domain envelope is not yet handled at the point of
- calling (as it relies on the previous block). */
-
-int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
- vorbis_info *vi=v->vi;
- codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- private_state *b=v->backend_state;
- int i,j;
-
- if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
-
- v->lW=v->W;
- v->W=vb->W;
- v->nW=-1;
-
- if((v->sequence==-1)||
- (v->sequence+1 != vb->sequence)){
- v->granulepos=-1; /* out of sequence; lose count */
- b->sample_count=-1;
- }
-
- v->sequence=vb->sequence;
-
- if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
- was called on block */
- int n=ci->blocksizes[v->W]/2;
- int n0=ci->blocksizes[0]/2;
- int n1=ci->blocksizes[1]/2;
-
- int thisCenter;
- int prevCenter;
-
- if(v->centerW){
- thisCenter=n1;
- prevCenter=0;
- }else{
- thisCenter=0;
- prevCenter=n1;
- }
-
- /* v->pcm is now used like a two-stage double buffer. We don't want
- to have to constantly shift *or* adjust memory usage. Don't
- accept a new block until the old is shifted out */
-
- /* overlap/add PCM */
-
- for(j=0;j<vi->channels;j++){
- /* the overlap/add section */
- if(v->lW){
- if(v->W){
- /* large/large */
- ogg_int32_t *pcm=v->pcm[j]+prevCenter;
- ogg_int32_t *p=vb->pcm[j];
- for(i=0;i<n1;i++)
- pcm[i]+=p[i];
- }else{
- /* large/small */
- ogg_int32_t *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
- ogg_int32_t *p=vb->pcm[j];
- for(i=0;i<n0;i++)
- pcm[i]+=p[i];
- }
- }else{
- if(v->W){
- /* small/large */
- ogg_int32_t *pcm=v->pcm[j]+prevCenter;
- ogg_int32_t *p=vb->pcm[j]+n1/2-n0/2;
- for(i=0;i<n0;i++)
- pcm[i]+=p[i];
- for(;i<n1/2+n0/2;i++)
- pcm[i]=p[i];
- }else{
- /* small/small */
- ogg_int32_t *pcm=v->pcm[j]+prevCenter;
- ogg_int32_t *p=vb->pcm[j];
- for(i=0;i<n0;i++)
- pcm[i]+=p[i];
- }
- }
-
- /* the copy section */
- {
- ogg_int32_t *pcm=v->pcm[j]+thisCenter;
- ogg_int32_t *p=vb->pcm[j]+n;
- for(i=0;i<n;i++)
- pcm[i]=p[i];
- }
- }
-
- if(v->centerW)
- v->centerW=0;
- else
- v->centerW=n1;
-
- /* deal with initial packet state; we do this using the explicit
- pcm_returned==-1 flag otherwise we're sensitive to first block
- being short or long */
-
- if(v->pcm_returned==-1){
- v->pcm_returned=thisCenter;
- v->pcm_current=thisCenter;
- }else{
- v->pcm_returned=prevCenter;
- v->pcm_current=prevCenter+
- ci->blocksizes[v->lW]/4+
- ci->blocksizes[v->W]/4;
- }
-
- }
-
- /* 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->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,
- we don't have a starting point to judge where the last frame
- is. For this reason, vorbisfile will always try to make sure
- it reads the last two marked pages in proper sequence */
-
- if(b->sample_count==-1){
- b->sample_count=0;
- }else{
- b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
- }
-
- if(v->granulepos==-1){
- if(vb->granulepos!=-1){ /* only set if we have a position to set to */
-
- v->granulepos=vb->granulepos;
-
- /* is this a short page? */
- if(b->sample_count>v->granulepos){
- /* corner case; if this is both the first and last audio page,
- then spec says the end is cut, not beginning */
- long extra=b->sample_count-vb->granulepos;
-
- /* we use ogg_int64_t for granule positions because a
- uint64 isn't universally available. Unfortunately,
- that means granposes can be 'negative' and result in
- extra being negative */
- if(extra<0)
- extra=0;
-
- if(vb->eofflag){
- /* trim the end */
- /* no preceeding granulepos; assume we started at zero (we'd
- have to in a short single-page stream) */
- /* granulepos could be -1 due to a seek, but that would result
- in a long coun`t, not short count */
-
- /* Guard against corrupt/malicious frames that set EOP and
- a backdated granpos; don't rewind more samples than we
- actually have */
- if(extra > v->pcm_current - v->pcm_returned)
- extra = v->pcm_current - v->pcm_returned;
-
- v->pcm_current-=extra;
- }else{
- /* trim the beginning */
- v->pcm_returned+=extra;
- if(v->pcm_returned>v->pcm_current)
- v->pcm_returned=v->pcm_current;
- }
-
- }
-
- }
- }else{
- v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
- if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
-
- if(v->granulepos>vb->granulepos){
- long extra=v->granulepos-vb->granulepos;
-
- if(extra)
- if(vb->eofflag){
- /* partial last frame. Strip the extra samples off */
-
- /* Guard against corrupt/malicious frames that set EOP and
- a backdated granpos; don't rewind more samples than we
- actually have */
- if(extra > v->pcm_current - v->pcm_returned)
- extra = v->pcm_current - v->pcm_returned;
-
- /* we use ogg_int64_t for granule positions because a
- uint64 isn't universally available. Unfortunately,
- that means granposes can be 'negative' and result in
- extra being negative */
- if(extra<0)
- extra=0;
-
- v->pcm_current-=extra;
-
- } /* else {Shouldn't happen *unless* the bitstream is out of
- spec. Either way, believe the bitstream } */
- } /* else {Shouldn't happen *unless* the bitstream is out of
- spec. Either way, believe the bitstream } */
- v->granulepos=vb->granulepos;
- }
- }
-
- /* Update, cleanup */
-
- if(vb->eofflag)v->eofflag=1;
- return(0);
-}
-
-/* pcm==NULL indicates we just want the pending samples, no more */
-int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm){
- vorbis_info *vi=v->vi;
- if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
- if(pcm){
- int i;
- for(i=0;i<vi->channels;i++)
- v->pcmret[i]=v->pcm[i]+v->pcm_returned;
- *pcm=v->pcmret;
- }
- return(v->pcm_current-v->pcm_returned);
- }
- return(0);
-}
-
-int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
- if(bytes && v->pcm_returned+bytes>v->pcm_current)return(OV_EINVAL);
- v->pcm_returned+=bytes;
- return(0);
-}
-
diff --git a/lib/tremor/block.h b/lib/tremor/block.h
deleted file mode 100644
index 5e193543..00000000
--- a/lib/tremor/block.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2008 *
- * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: shared block functions
-
- ********************************************************************/
-
-#ifndef _V_BLOCK_
-#define _V_BLOCK_
-
-extern void _vorbis_block_ripcord(vorbis_block *vb);
-extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes);
-
-#endif
diff --git a/lib/tremor/codebook.c b/lib/tremor/codebook.c
index 1e1ae8a9..85a46eb2 100644
--- a/lib/tremor/codebook.c
+++ b/lib/tremor/codebook.c
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -18,77 +18,385 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
-#include <ogg/ogg.h>
+#include "tremor_ogg.h"
#include "ivorbiscodec.h"
#include "codebook.h"
#include "misc.h"
+#include "os.h"
-/* unpacks a codebook from the packet buffer into the codebook struct,
- readies the codebook auxiliary structures for decode *************/
-static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
- long i,j;
- static_codebook *s=_ogg_calloc(1,sizeof(*s));
+
+/**** pack/unpack helpers ******************************************/
+int _ilog(unsigned int v){
+ int ret=0;
+ while(v){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+static tremor_ogg_uint32_t decpack(long entry,long used_entry,long quantvals,
+ codebook *b,tremor_oggpack_buffer *opb,int maptype){
+ tremor_ogg_uint32_t ret=0;
+ int j;
+
+ switch(b->dec_type){
+
+ case 0:
+ return (tremor_ogg_uint32_t)entry;
+
+ case 1:
+ if(maptype==1){
+ /* vals are already read into temporary column vector here */
+ for(j=0;j<b->dim;j++){
+ tremor_ogg_uint32_t off=entry%quantvals;
+ entry/=quantvals;
+ ret|=((tremor_ogg_uint16_t *)(b->q_val))[off]<<(b->q_bits*j);
+ }
+ }else{
+ for(j=0;j<b->dim;j++)
+ ret|=tremor_oggpack_read(opb,b->q_bits)<<(b->q_bits*j);
+ }
+ return ret;
+
+ case 2:
+ for(j=0;j<b->dim;j++){
+ tremor_ogg_uint32_t off=entry%quantvals;
+ entry/=quantvals;
+ ret|=off<<(b->q_pack*j);
+ }
+ return ret;
+
+ case 3:
+ return (tremor_ogg_uint32_t)used_entry;
+
+ }
+ return 0; /* silence compiler */
+}
+
+/* 32 bit float (not IEEE; nonnormalized mantissa +
+ biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
+ Why not IEEE? It's just not that important here. */
+
+static tremor_ogg_int32_t _float32_unpack(long val,int *point){
+ long mant=val&0x1fffff;
+ int sign=val&0x80000000;
+
+ *point=((val&0x7fe00000L)>>21)-788;
+
+ if(mant){
+ while(!(mant&0x40000000)){
+ mant<<=1;
+ *point-=1;
+ }
+ if(sign)mant= -mant;
+ }else{
+ *point=-9999;
+ }
+ return mant;
+}
+
+/* choose the smallest supported node size that fits our decode table.
+ Legal bytewidths are 1/1 1/2 2/2 2/4 4/4 */
+static int _determine_node_bytes(long used, int leafwidth){
+
+ /* special case small books to size 4 to avoid multiple special
+ cases in repack */
+ if(used<2)
+ return 4;
+
+ if(leafwidth==3)leafwidth=4;
+ if(_ilog(3*used-6)+1 <= leafwidth*4)
+ return leafwidth/2?leafwidth/2:1;
+ return leafwidth;
+}
+
+/* convenience/clarity; leaves are specified as multiple of node word
+ size (1 or 2) */
+static int _determine_leaf_words(int nodeb, int leafwidth){
+ if(leafwidth>nodeb)return 2;
+ return 1;
+}
+
+/* given a list of word lengths, number of used entries, and byte
+ width of a leaf, generate the decode table */
+static int _make_words(char *l,long n,tremor_ogg_uint32_t *r,long quantvals,
+ codebook *b, tremor_oggpack_buffer *opb,int maptype){
+ long i,j,count=0;
+ long top=0;
+ tremor_ogg_uint32_t marker[33];
+
+ if(n<2){
+ r[0]=0x80000000;
+ }else{
+ memset(marker,0,sizeof(marker));
+
+ for(i=0;i<n;i++){
+ long length=l[i];
+ if(length){
+ tremor_ogg_uint32_t entry=marker[length];
+ long chase=0;
+ if(count && !entry)return -1; /* overpopulated tree! */
+
+ /* chase the tree as far as it's already populated, fill in past */
+ for(j=0;j<length-1;j++){
+ int bit=(entry>>(length-j-1))&1;
+ if(chase>=top){
+ top++;
+ r[chase*2]=top;
+ r[chase*2+1]=0;
+ }else
+ if(!r[chase*2+bit])
+ r[chase*2+bit]=top;
+ chase=r[chase*2+bit];
+ }
+ {
+ int bit=(entry>>(length-j-1))&1;
+ if(chase>=top){
+ top++;
+ r[chase*2+1]=0;
+ }
+ r[chase*2+bit]= decpack(i,count++,quantvals,b,opb,maptype) |
+ 0x80000000;
+ }
+
+ /* Look to see if the next shorter marker points to the node
+ above. if so, update it and repeat. */
+ for(j=length;j>0;j--){
+ if(marker[j]&1){
+ marker[j]=marker[j-1]<<1;
+ break;
+ }
+ marker[j]++;
+ }
+
+ /* prune the tree; the implicit invariant says all the longer
+ markers were dangling from our just-taken node. Dangle them
+ from our *new* node. */
+ for(j=length+1;j<33;j++)
+ if((marker[j]>>1) == entry){
+ entry=marker[j];
+ marker[j]=marker[j-1]<<1;
+ }else
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int _make_decode_table(codebook *s,char *lengthlist,long quantvals,
+ tremor_oggpack_buffer *opb,int maptype){
+ int i;
+ tremor_ogg_uint32_t *work;
+
+ if(s->dec_nodeb==4){
+ s->dec_table=_tremor_ogg_malloc((s->used_entries*2+1)*sizeof(*work));
+ /* +1 (rather than -2) is to accommodate 0 and 1 sized books,
+ which are specialcased to nodeb==4 */
+ if(_make_words(lengthlist,s->entries,
+ s->dec_table,quantvals,s,opb,maptype))return 1;
+
+ return 0;
+ }
+
+ work=alloca((s->used_entries*2-2)*sizeof(*work));
+ if(_make_words(lengthlist,s->entries,work,quantvals,s,opb,maptype))return 1;
+ s->dec_table=_tremor_ogg_malloc((s->used_entries*(s->dec_leafw+1)-2)*
+ s->dec_nodeb);
+
+ if(s->dec_leafw==1){
+ switch(s->dec_nodeb){
+ case 1:
+ for(i=0;i<s->used_entries*2-2;i++)
+ ((unsigned char *)s->dec_table)[i]=
+ ((work[i] & 0x80000000UL) >> 24) | work[i];
+ break;
+ case 2:
+ for(i=0;i<s->used_entries*2-2;i++)
+ ((tremor_ogg_uint16_t *)s->dec_table)[i]=
+ ((work[i] & 0x80000000UL) >> 16) | work[i];
+ break;
+ }
+
+ }else{
+ /* more complex; we have to do a two-pass repack that updates the
+ node indexing. */
+ long top=s->used_entries*3-2;
+ if(s->dec_nodeb==1){
+ unsigned char *out=(unsigned char *)s->dec_table;
+
+ for(i=s->used_entries*2-4;i>=0;i-=2){
+ if(work[i]&0x80000000UL){
+ if(work[i+1]&0x80000000UL){
+ top-=4;
+ out[top]=(work[i]>>8 & 0x7f)|0x80;
+ out[top+1]=(work[i+1]>>8 & 0x7f)|0x80;
+ out[top+2]=work[i] & 0xff;
+ out[top+3]=work[i+1] & 0xff;
+ }else{
+ top-=3;
+ out[top]=(work[i]>>8 & 0x7f)|0x80;
+ out[top+1]=work[work[i+1]*2];
+ out[top+2]=work[i] & 0xff;
+ }
+ }else{
+ if(work[i+1]&0x80000000UL){
+ top-=3;
+ out[top]=work[work[i]*2];
+ out[top+1]=(work[i+1]>>8 & 0x7f)|0x80;
+ out[top+2]=work[i+1] & 0xff;
+ }else{
+ top-=2;
+ out[top]=work[work[i]*2];
+ out[top+1]=work[work[i+1]*2];
+ }
+ }
+ work[i]=top;
+ }
+ }else{
+ tremor_ogg_uint16_t *out=(tremor_ogg_uint16_t *)s->dec_table;
+ for(i=s->used_entries*2-4;i>=0;i-=2){
+ if(work[i]&0x80000000UL){
+ if(work[i+1]&0x80000000UL){
+ top-=4;
+ out[top]=(work[i]>>16 & 0x7fff)|0x8000;
+ out[top+1]=(work[i+1]>>16 & 0x7fff)|0x8000;
+ out[top+2]=work[i] & 0xffff;
+ out[top+3]=work[i+1] & 0xffff;
+ }else{
+ top-=3;
+ out[top]=(work[i]>>16 & 0x7fff)|0x8000;
+ out[top+1]=work[work[i+1]*2];
+ out[top+2]=work[i] & 0xffff;
+ }
+ }else{
+ if(work[i+1]&0x80000000UL){
+ top-=3;
+ out[top]=work[work[i]*2];
+ out[top+1]=(work[i+1]>>16 & 0x7fff)|0x8000;
+ out[top+2]=work[i+1] & 0xffff;
+ }else{
+ top-=2;
+ out[top]=work[work[i]*2];
+ out[top+1]=work[work[i+1]*2];
+ }
+ }
+ work[i]=top;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* most of the time, entries%dimensions == 0, but we need to be
+ well defined. We define that the possible vales at each
+ scalar is values == entries/dim. If entries%dim != 0, we'll
+ have 'too few' values (values*dim<entries), which means that
+ we'll have 'left over' entries; left over entries use zeroed
+ values (and are wasted). So don't generate codebooks like
+ that */
+/* there might be a straightforward one-line way to do the below
+ that's portable and totally safe against roundoff, but I haven't
+ thought of it. Therefore, we opt on the side of caution */
+long _book_maptype1_quantvals(codebook *b){
+ /* get us a starting hint, we'll polish it below */
+ int bits=_ilog(b->entries);
+ int vals=b->entries>>((bits-1)*(b->dim-1)/b->dim);
+
+ while(1){
+ long acc=1;
+ long acc1=1;
+ int i;
+ for(i=0;i<b->dim;i++){
+ acc*=vals;
+ acc1*=vals+1;
+ }
+ if(acc<=b->entries && acc1>b->entries){
+ return(vals);
+ }else{
+ if(acc>b->entries){
+ vals--;
+ }else{
+ vals++;
+ }
+ }
+ }
+}
+
+void vorbis_book_clear(codebook *b){
+ /* static book is not cleared; we're likely called on the lookup and
+ the static codebook belongs to the info struct */
+ if(b->q_val)_tremor_ogg_free(b->q_val);
+ if(b->dec_table)_tremor_ogg_free(b->dec_table);
+
+ memset(b,0,sizeof(*b));
+}
+
+int vorbis_book_unpack(tremor_oggpack_buffer *opb,codebook *s){
+ char *lengthlist=NULL;
+ int quantvals=0;
+ long i,j;
+ int maptype;
+
+ memset(s,0,sizeof(*s));
/* make sure alignment is correct */
- if(oggpack_read(opb,24)!=0x564342)goto _eofout;
+ if(tremor_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=tremor_oggpack_read(opb,16);
+ s->entries=tremor_oggpack_read(opb,24);
if(s->entries==-1)goto _eofout;
- if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
-
/* codeword ordering.... length ordered or unordered? */
- switch((int)oggpack_read(opb,1)){
- case 0:{
- long unused;
- /* allocated but unused entries? */
- unused=oggpack_read(opb,1);
- if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb))
- goto _eofout;
+ switch((int)tremor_oggpack_read(opb,1)){
+ case 0:
/* unordered */
- s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
+ lengthlist=(char *)alloca(sizeof(*lengthlist)*s->entries);
/* allocated but unused entries? */
- if(unused){
+ if(tremor_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(tremor_oggpack_read(opb,1)){
+ long num=tremor_oggpack_read(opb,5);
if(num==-1)goto _eofout;
- s->lengthlist[i]=num+1;
+ lengthlist[i]=num+1;
+ s->used_entries++;
+ if(num+1>s->dec_maxlength)s->dec_maxlength=num+1;
}else
- s->lengthlist[i]=0;
+ lengthlist[i]=0;
}
}else{
/* all entries used; no tagging */
+ s->used_entries=s->entries;
for(i=0;i<s->entries;i++){
- long num=oggpack_read(opb,5);
+ long num=tremor_oggpack_read(opb,5);
if(num==-1)goto _eofout;
- s->lengthlist[i]=num+1;
+ lengthlist[i]=num+1;
+ if(num+1>s->dec_maxlength)s->dec_maxlength=num+1;
}
}
break;
- }
case 1:
/* ordered */
{
- long length=oggpack_read(opb,5)+1;
- if(length==0)goto _eofout;
- s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
+ long length=tremor_oggpack_read(opb,5)+1;
+ s->used_entries=s->entries;
+ lengthlist=(char *)alloca(sizeof(*lengthlist)*s->entries);
+
for(i=0;i<s->entries;){
- long num=oggpack_read(opb,_ilog(s->entries-i));
+ long num=tremor_oggpack_read(opb,_ilog(s->entries-i));
if(num==-1)goto _eofout;
- if(length>32 || num>s->entries-i ||
- (num>0 && (num-1)>>(length>>1)>>((length+1)>>1))>0){
- goto _errout;
- }
- for(j=0;j<num;j++,i++)
- s->lengthlist[i]=length;
+ for(j=0;j<num && i<s->entries;j++,i++)
+ lengthlist[i]=length;
+ s->dec_maxlength=length;
length++;
}
}
@@ -97,295 +405,393 @@ static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
/* EOF */
goto _eofout;
}
-
+
+
/* Do we have a mapping to unpack? */
- switch((s->maptype=oggpack_read(opb,4))){
+
+ if((maptype=tremor_oggpack_read(opb,4))>0){
+ s->q_min=_float32_unpack(tremor_oggpack_read(opb,32),&s->q_minp);
+ s->q_del=_float32_unpack(tremor_oggpack_read(opb,32),&s->q_delp);
+ s->q_bits=tremor_oggpack_read(opb,4)+1;
+ s->q_seq=tremor_oggpack_read(opb,1);
+
+ s->q_del>>=s->q_bits;
+ s->q_delp+=s->q_bits;
+ }
+
+ switch(maptype){
case 0:
- /* no mapping */
+
+ /* no mapping; decode type 0 */
+
+ /* how many bytes for the indexing? */
+ /* this is the correct boundary here; we lose one bit to
+ node/leaf mark */
+ s->dec_nodeb=_determine_node_bytes(s->used_entries,_ilog(s->entries)/8+1);
+ s->dec_leafw=_determine_leaf_words(s->dec_nodeb,_ilog(s->entries)/8+1);
+ s->dec_type=0;
+
+ if(_make_decode_table(s,lengthlist,quantvals,opb,maptype)) goto _errout;
break;
- case 1: case 2:
- /* 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);
- if(s->q_sequencep==-1)goto _eofout;
+ case 1:
+ /* mapping type 1; implicit values by lattice position */
+ quantvals=_book_maptype1_quantvals(s);
+
+ /* dec_type choices here are 1,2; 3 doesn't make sense */
{
- int quantvals=0;
- switch(s->maptype){
- case 1:
- quantvals=(s->dim==0?0:_book_maptype1_quantvals(s));
- break;
- case 2:
- quantvals=s->entries*s->dim;
- break;
- }
+ /* packed values */
+ long total1=(s->q_bits*s->dim+8)/8; /* remember flag bit */
+ /* vector of column offsets; remember flag bit */
+ long total2=(_ilog(quantvals-1)*s->dim+8)/8+(s->q_bits+7)/8;
+
- /* quantized values */
- if((quantvals*s->q_quant+7)>>3>opb->storage-oggpack_bytes(opb))
- goto _eofout;
- s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
- for(i=0;i<quantvals;i++)
- s->quantlist[i]=oggpack_read(opb,s->q_quant);
+ if(total1<=4 && total1<=total2){
+ /* use dec_type 1: vector of packed values */
+
+ /* need quantized values before */
+ s->q_val=alloca(sizeof(tremor_ogg_uint16_t)*quantvals);
+ for(i=0;i<quantvals;i++)
+ ((tremor_ogg_uint16_t *)s->q_val)[i]=tremor_oggpack_read(opb,s->q_bits);
+
+ if(tremor_oggpack_eop(opb)){
+ s->q_val=0; /* cleanup must not free alloca memory */
+ goto _eofout;
+ }
+
+ s->dec_type=1;
+ s->dec_nodeb=_determine_node_bytes(s->used_entries,
+ (s->q_bits*s->dim+8)/8);
+ s->dec_leafw=_determine_leaf_words(s->dec_nodeb,
+ (s->q_bits*s->dim+8)/8);
+ if(_make_decode_table(s,lengthlist,quantvals,opb,maptype)){
+ s->q_val=0; /* cleanup must not free alloca memory */
+ goto _errout;
+ }
+
+ s->q_val=0; /* about to go out of scope; _make_decode_table
+ was using it */
+
+ }else{
+ /* use dec_type 2: packed vector of column offsets */
+
+ /* need quantized values before */
+ if(s->q_bits<=8){
+ s->q_val=_tremor_ogg_malloc(quantvals);
+ for(i=0;i<quantvals;i++)
+ ((unsigned char *)s->q_val)[i]=tremor_oggpack_read(opb,s->q_bits);
+ }else{
+ s->q_val=_tremor_ogg_malloc(quantvals*2);
+ for(i=0;i<quantvals;i++)
+ ((tremor_ogg_uint16_t *)s->q_val)[i]=tremor_oggpack_read(opb,s->q_bits);
+ }
+
+ if(tremor_oggpack_eop(opb))goto _eofout;
+
+ s->q_pack=_ilog(quantvals-1);
+ s->dec_type=2;
+ s->dec_nodeb=_determine_node_bytes(s->used_entries,
+ (_ilog(quantvals-1)*s->dim+8)/8);
+ s->dec_leafw=_determine_leaf_words(s->dec_nodeb,
+ (_ilog(quantvals-1)*s->dim+8)/8);
+ if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout;
+
+ }
+ }
+ break;
+ case 2:
+
+ /* mapping type 2; explicit array of values */
+ quantvals=s->entries*s->dim;
+ /* dec_type choices here are 1,3; 2 is not possible */
+
+ if( (s->q_bits*s->dim+8)/8 <=4){ /* remember flag bit */
+ /* use dec_type 1: vector of packed values */
+
+ s->dec_type=1;
+ s->dec_nodeb=_determine_node_bytes(s->used_entries,(s->q_bits*s->dim+8)/8);
+ s->dec_leafw=_determine_leaf_words(s->dec_nodeb,(s->q_bits*s->dim+8)/8);
+ if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout;
- if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
+ }else{
+ /* use dec_type 3: scalar offset into packed value array */
+
+ s->dec_type=3;
+ s->dec_nodeb=_determine_node_bytes(s->used_entries,_ilog(s->used_entries-1)/8+1);
+ s->dec_leafw=_determine_leaf_words(s->dec_nodeb,_ilog(s->used_entries-1)/8+1);
+ if(_make_decode_table(s,lengthlist,quantvals,opb,maptype))goto _errout;
+
+ /* get the vals & pack them */
+ s->q_pack=(s->q_bits+7)/8*s->dim;
+ s->q_val=_tremor_ogg_malloc(s->q_pack*s->used_entries);
+
+ if(s->q_bits<=8){
+ for(i=0;i<s->used_entries*s->dim;i++)
+ ((unsigned char *)(s->q_val))[i]=tremor_oggpack_read(opb,s->q_bits);
+ }else{
+ for(i=0;i<s->used_entries*s->dim;i++)
+ ((tremor_ogg_uint16_t *)(s->q_val))[i]=tremor_oggpack_read(opb,s->q_bits);
+ }
}
break;
default:
goto _errout;
}
- /* all set */
- return(s);
-
+ if(tremor_oggpack_eop(opb))goto _eofout;
+
+ return 0;
_errout:
_eofout:
- vorbis_staticbook_destroy(s);
- return(NULL);
+ vorbis_book_clear(s);
+ return -1;
}
-/* the 'eliminate the decode tree' optimization actually requires the
- codewords to be MSb first, not LSb. This is an annoying inelegancy
- (and one of the first places where carefully thought out design
- turned out to be wrong; Vorbis II and future Ogg codecs should go
- to an MSb bitpacker), but not actually the huge hit it appears to
- be. The first-stage decode table catches most words so that
- bitreverse is not in the main execution path. */
-
-static ogg_uint32_t bitreverse(ogg_uint32_t x){
- x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
- x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
- x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
- x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
- return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
-}
-
-STIN long decode_packed_entry_number(codebook *book,
- oggpack_buffer *b){
+static inline tremor_ogg_uint32_t decode_packed_entry_number(codebook *book,
+ tremor_oggpack_buffer *b){
+ tremor_ogg_uint32_t chase=0;
int read=book->dec_maxlength;
- long lo,hi;
- long lok = oggpack_look(b,book->dec_firsttablen);
-
- if (lok >= 0) {
- long entry = book->dec_firsttable[lok];
- if(entry&0x80000000UL){
- lo=(entry>>15)&0x7fff;
- hi=book->used_entries-(entry&0x7fff);
- }else{
- oggpack_adv(b, book->dec_codelengths[entry-1]);
- return(entry-1);
- }
- }else{
- lo=0;
- hi=book->used_entries;
- }
-
- lok = oggpack_look(b, read);
-
+ long lok = tremor_oggpack_look(b,read),i;
+
while(lok<0 && read>1)
- lok = oggpack_look(b, --read);
+ lok = tremor_oggpack_look(b, --read);
if(lok<0){
- oggpack_adv(b,1); /* force eop */
+ tremor_oggpack_adv(b,1); /* force eop */
return -1;
}
- /* bisect search for the codeword in the ordered list */
- {
- ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
+ /* chase the tree with the bits we got */
+ if(book->dec_nodeb==1){
+ if(book->dec_leafw==1){
+
+ /* 8/8 */
+ unsigned char *t=(unsigned char *)book->dec_table;
+ for(i=0;i<read;i++){
+ chase=t[chase*2+((lok>>i)&1)];
+ if(chase&0x80UL)break;
+ }
+ chase&=0x7fUL;
- while(hi-lo>1){
- long p=(hi-lo)>>1;
- long test=book->codelist[lo+p]>testword;
- lo+=p&(test-1);
- hi-=p&(-test);
+ }else{
+
+ /* 8/16 */
+ unsigned char *t=(unsigned char *)book->dec_table;
+ for(i=0;i<read;i++){
+ int bit=(lok>>i)&1;
+ int next=t[chase+bit];
+ if(next&0x80){
+ chase= (next<<8) | t[chase+bit+1+(!bit || t[chase]&0x80)];
+ break;
+ }
+ chase=next;
+ }
+ chase&=0x7fffUL;
}
- if(book->dec_codelengths[lo]<=read){
- oggpack_adv(b, book->dec_codelengths[lo]);
- return(lo);
+ }else{
+ if(book->dec_nodeb==2){
+ if(book->dec_leafw==1){
+
+ /* 16/16 */
+ for(i=0;i<read;i++){
+ chase=((tremor_ogg_uint16_t *)(book->dec_table))[chase*2+((lok>>i)&1)];
+ if(chase&0x8000UL)break;
+ }
+ chase&=0x7fffUL;
+
+ }else{
+
+ /* 16/32 */
+ tremor_ogg_uint16_t *t=(tremor_ogg_uint16_t *)book->dec_table;
+ for(i=0;i<read;i++){
+ int bit=(lok>>i)&1;
+ int next=t[chase+bit];
+ if(next&0x8000){
+ chase= (next<<16) | t[chase+bit+1+(!bit || t[chase]&0x8000)];
+ break;
+ }
+ chase=next;
+ }
+ chase&=0x7fffffffUL;
+ }
+
+ }else{
+
+ for(i=0;i<read;i++){
+ chase=((tremor_ogg_uint32_t *)(book->dec_table))[chase*2+((lok>>i)&1)];
+ if(chase&0x80000000UL)break;
+ }
+ chase&=0x7fffffffUL;
+
}
}
- oggpack_adv(b, read+1);
+ if(i<read){
+ tremor_oggpack_adv(b,i+1);
+ return chase;
+ }
+ tremor_oggpack_adv(b,read+1);
return(-1);
}
-/* Decode side is specced and easier, because we don't need to find
- matches using different criteria; we simply read and map. There are
- two things we need to do 'depending':
-
- We may need to support interleave. We don't really, but it's
- convenient to do it here rather than rebuild the vector later.
+/* returns the [original, not compacted] entry number or -1 on eof *********/
+long vorbis_book_decode(codebook *book, tremor_oggpack_buffer *b){
+ if(book->dec_type)return -1;
+ return decode_packed_entry_number(book,b);
+}
+
+int decode_map(codebook *s, tremor_oggpack_buffer *b, tremor_ogg_int32_t *v, int point){
+ tremor_ogg_uint32_t entry = decode_packed_entry_number(s,b);
+ int i;
+ if(tremor_oggpack_eop(b))return(-1);
+
+ /* according to decode type */
+ switch(s->dec_type){
+ case 1:{
+ /* packed vector of values */
+ int mask=(1<<s->q_bits)-1;
+ for(i=0;i<s->dim;i++){
+ v[i]=entry&mask;
+ entry>>=s->q_bits;
+ }
+ break;
+ }
+ case 2:{
+ /* packed vector of column offsets */
+ int mask=(1<<s->q_pack)-1;
+ for(i=0;i<s->dim;i++){
+ if(s->q_bits<=8)
+ v[i]=((unsigned char *)(s->q_val))[entry&mask];
+ else
+ v[i]=((tremor_ogg_uint16_t *)(s->q_val))[entry&mask];
+ entry>>=s->q_pack;
+ }
+ break;
+ }
+ case 3:{
+ /* offset into array */
+ void *ptr=s->q_val+entry*s->q_pack;
- Cascades may be additive or multiplicitive; this is not inherent in
- the codebook, but set in the code using the codebook. Like
- interleaving, it's easiest to do it here.
- addmul==0 -> declarative (set the value)
- addmul==1 -> additive
- addmul==2 -> multiplicitive */
+ if(s->q_bits<=8){
+ for(i=0;i<s->dim;i++)
+ v[i]=((unsigned char *)ptr)[i];
+ }else{
+ for(i=0;i<s->dim;i++)
+ v[i]=((tremor_ogg_uint16_t *)ptr)[i];
+ }
+ break;
+ }
+ default:
+ return -1;
+ }
-/* returns the [original, not compacted] entry number or -1 on eof *********/
-long vorbis_book_decode(codebook *book, oggpack_buffer *b){
- if(book->used_entries>0){
- long packed_entry=decode_packed_entry_number(book,b);
- if(packed_entry>=0)
- return(book->dec_index[packed_entry]);
+ /* we have the unpacked multiplicands; compute final vals */
+ {
+ int shiftM=point-s->q_delp;
+ tremor_ogg_int32_t add=point-s->q_minp;
+ if(add>0)
+ add= s->q_min >> add;
+ else
+ add= s->q_min << -add;
+
+ if(shiftM>0)
+ for(i=0;i<s->dim;i++)
+ v[i]= add + ((v[i] * s->q_del) >> shiftM);
+ else
+ for(i=0;i<s->dim;i++)
+ v[i]= add + ((v[i] * s->q_del) << -shiftM);
+
+ if(s->q_seq)
+ for(i=1;i<s->dim;i++)
+ v[i]+=v[i-1];
}
- /* if there's no dec_index, the codebook unpacking isn't collapsed */
- return(-1);
+ return 0;
}
/* returns 0 on OK or -1 on eof *************************************/
-/* decode vector / dim granularity gaurding is done in the upper layer */
-long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a,
- oggpack_buffer *b,int n,int point){
- if(book->used_entries>0){
+/* decode vector / dim granularity guarding is done in the upper layer */
+long vorbis_book_decodevs_add(codebook *book,tremor_ogg_int32_t *a,
+ tremor_oggpack_buffer *b,int n,int point){
+ if(book->used_entries>0){
int step=n/book->dim;
- long *entry = (long *)alloca(sizeof(*entry)*step);
- ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step);
+ tremor_ogg_int32_t *v = (tremor_ogg_int32_t *)alloca(sizeof(*v)*book->dim);
int i,j,o;
- int shift=point-book->binarypoint;
- if(shift>=0){
- for (i = 0; i < step; i++) {
- entry[i]=decode_packed_entry_number(book,b);
- if(entry[i]==-1)return(-1);
- t[i] = book->valuelist+entry[i]*book->dim;
- }
- for(i=0,o=0;i<book->dim;i++,o+=step)
- for (j=0;o+j<n && j<step;j++)
- a[o+j]+=t[j][i]>>shift;
- }else{
- for (i = 0; i < step; i++) {
- entry[i]=decode_packed_entry_number(book,b);
- if(entry[i]==-1)return(-1);
- t[i] = book->valuelist+entry[i]*book->dim;
- }
- for(i=0,o=0;i<book->dim;i++,o+=step)
- for (j=0;o+j<n && j<step;j++)
- a[o+j]+=t[j][i]<<-shift;
+ for (j=0;j<step;j++){
+ if(decode_map(book,b,v,point))return -1;
+ for(i=0,o=j;i<book->dim;i++,o+=step)
+ a[o]+=v[i];
}
}
- return(0);
+ return 0;
}
-/* decode vector / dim granularity gaurding is done in the upper layer */
-long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a,
- oggpack_buffer *b,int n,int point){
+/* decode vector / dim granularity guarding is done in the upper layer */
+long vorbis_book_decodev_add(codebook *book,tremor_ogg_int32_t *a,
+ tremor_oggpack_buffer *b,int n,int point){
if(book->used_entries>0){
- int i,j,entry;
- ogg_int32_t *t;
- int shift=point-book->binarypoint;
+ tremor_ogg_int32_t *v = (tremor_ogg_int32_t *)alloca(sizeof(*v)*book->dim);
+ int i,j;
- if(shift>=0){
- for(i=0;i<n;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- t = book->valuelist+entry*book->dim;
- for (j=0;i<n && j<book->dim;)
- a[i++]+=t[j++]>>shift;
- }
- }else{
- for(i=0;i<n;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- t = book->valuelist+entry*book->dim;
- for (j=0;i<n && j<book->dim;)
- a[i++]+=t[j++]<<-shift;
- }
+ for(i=0;i<n;){
+ if(decode_map(book,b,v,point))return -1;
+ for (j=0;i<n && j<book->dim;j++)
+ a[i++]+=v[j];
}
}
- return(0);
+ return 0;
}
/* unlike the others, we guard against n not being an integer number
- of <dim> internally rather than in the upper layer (called only by
- floor0) */
-long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a,
- oggpack_buffer *b,int n,int point){
+ * of <dim> internally rather than in the upper layer (called only by
+ * floor0) */
+long vorbis_book_decodev_set(codebook *book,tremor_ogg_int32_t *a,
+ tremor_oggpack_buffer *b,int n,int point){
if(book->used_entries>0){
- int i,j,entry;
- ogg_int32_t *t;
- int shift=point-book->binarypoint;
+ tremor_ogg_int32_t *v = (tremor_ogg_int32_t *)alloca(sizeof(*v)*book->dim);
+ int i,j;
- if(shift>=0){
-
- for(i=0;i<n;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- t = book->valuelist+entry*book->dim;
- for (j=0;i<n && j<book->dim;){
- a[i++]=t[j++]>>shift;
- }
- }
- }else{
-
- for(i=0;i<n;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- t = book->valuelist+entry*book->dim;
- for (j=0;i<n && j<book->dim;){
- a[i++]=t[j++]<<-shift;
- }
- }
+ for(i=0;i<n;){
+ if(decode_map(book,b,v,point))return -1;
+ for (j=0;i<n && j<book->dim;j++)
+ a[i++]=v[j];
}
}else{
-
- int i,j;
+ int i;
+
for(i=0;i<n;){
a[i++]=0;
}
}
- return(0);
+
+ return 0;
}
-/* decode vector / dim granularity gaurding is done in the upper layer */
-long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,\
+/* decode vector / dim granularity guarding is done in the upper layer */
+long vorbis_book_decodevv_add(codebook *book,tremor_ogg_int32_t **a,
long offset,int ch,
- oggpack_buffer *b,int n,int point){
+ tremor_oggpack_buffer *b,int n,int point){
if(book->used_entries>0){
- long i,j,entry;
+
+ tremor_ogg_int32_t *v = (tremor_ogg_int32_t *)alloca(sizeof(*v)*book->dim);
+ long i,j;
int chptr=0;
- int shift=point-book->binarypoint;
- int m=offset+n;
- if(shift>=0){
-
- for(i=offset;i<m;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- {
- const ogg_int32_t *t = book->valuelist+entry*book->dim;
- for (j=0;i<m && j<book->dim;j++){
- a[chptr++][i]+=t[j]>>shift;
- if(chptr==ch){
- chptr=0;
- i++;
- }
- }
- }
- }
- }else{
-
- for(i=offset;i<m;){
- entry = decode_packed_entry_number(book,b);
- if(entry==-1)return(-1);
- {
- const ogg_int32_t *t = book->valuelist+entry*book->dim;
- for (j=0;i<m && j<book->dim;j++){
- a[chptr++][i]+=t[j]<<-shift;
- if(chptr==ch){
- chptr=0;
- i++;
- }
- }
+ long m=offset+n;
+
+ for(i=offset;i<m;){
+ if(decode_map(book,b,v,point))return -1;
+ for (j=0;i<m && j<book->dim;j++){
+ a[chptr++][i]+=v[j];
+ if(chptr==ch){
+ chptr=0;
+ i++;
}
}
}
}
- return(0);
+
+ return 0;
}
diff --git a/lib/tremor/codebook.h b/lib/tremor/codebook.h
index bb139426..a32f0f7a 100644
--- a/lib/tremor/codebook.h
+++ b/lib/tremor/codebook.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -18,82 +18,46 @@
#ifndef _V_CODEBOOK_H_
#define _V_CODEBOOK_H_
-#include <ogg/ogg.h>
-
-/* This structure encapsulates huffman and VQ style encoding books; it
- doesn't do anything specific to either.
-
- valuelist/quantlist are nonNULL (and q_* significant) only if
- there's entry->value mapping to be done.
-
- If encode-side mapping must be done (and thus the entry needs to be
- hunted), the auxiliary encode pointer will point to a decision
- tree. This is true of both VQ and huffman, but is mostly useful
- with VQ.
-
-*/
-
-typedef struct static_codebook{
- long dim; /* codebook dimensions (elements per vector) */
- long entries; /* codebook entries */
- long *lengthlist; /* codeword lengths in bits */
-
- /* mapping ***************************************************************/
- int maptype; /* 0=none
- 1=implicitly populated values from map column
- 2=listed arbitrary values */
-
- /* The below does a linear, single monotonic sequence mapping. */
- long q_min; /* packed 32 bit float; quant value 0 maps to minval */
- long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */
- int q_quant; /* bits: 0 < quant <= 16 */
- int q_sequencep; /* bitflag */
-
- long *quantlist; /* map == 1: (int)(entries^(1/dim)) element column map
- map == 2: list of dim*entries quantized entry vals
- */
-} static_codebook;
+#include "tremor_ogg.h"
typedef struct codebook{
- long dim; /* codebook dimensions (elements per vector) */
- long entries; /* codebook entries */
- long used_entries; /* populated codebook entries */
-
- /* the below are ordered by bitreversed codeword and only used
- entries are populated */
- int binarypoint;
- ogg_int32_t *valuelist; /* list of dim*entries actual entry values */
- ogg_uint32_t *codelist; /* list of bitstream codewords for each entry */
-
- int *dec_index;
- char *dec_codelengths;
- ogg_uint32_t *dec_firsttable;
- int dec_firsttablen;
- int dec_maxlength;
-
- long q_min; /* packed 32 bit float; quant value 0 maps to minval */
- long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */
+ long dim; /* codebook dimensions (elements per vector) */
+ long entries; /* codebook entries */
+ long used_entries; /* populated codebook entries */
+
+ int dec_maxlength;
+ void *dec_table;
+ int dec_nodeb;
+ int dec_leafw;
+ int dec_type; /* 0 = entry number
+ 1 = packed vector of values
+ 2 = packed vector of column offsets, maptype 1
+ 3 = scalar offset into value array, maptype 2 */
+
+ tremor_ogg_int32_t q_min;
+ int q_minp;
+ tremor_ogg_int32_t q_del;
+ int q_delp;
+ int q_seq;
+ int q_bits;
+ int q_pack;
+ void *q_val;
} codebook;
-extern void vorbis_staticbook_destroy(static_codebook *b);
-extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source);
-
extern void vorbis_book_clear(codebook *b);
-extern long _book_maptype1_quantvals(const static_codebook *b);
-
-extern static_codebook *vorbis_staticbook_unpack(oggpack_buffer *b);
-
-extern long vorbis_book_decode(codebook *book, oggpack_buffer *b);
-extern long vorbis_book_decodevs_add(codebook *book, ogg_int32_t *a,
- oggpack_buffer *b,int n,int point);
-extern long vorbis_book_decodev_set(codebook *book, ogg_int32_t *a,
- oggpack_buffer *b,int n,int point);
-extern long vorbis_book_decodev_add(codebook *book, ogg_int32_t *a,
- oggpack_buffer *b,int n,int point);
-extern long vorbis_book_decodevv_add(codebook *book, ogg_int32_t **a,
+extern int vorbis_book_unpack(tremor_oggpack_buffer *b,codebook *c);
+
+extern long vorbis_book_decode(codebook *book, tremor_oggpack_buffer *b);
+extern long vorbis_book_decodevs_add(codebook *book, tremor_ogg_int32_t *a,
+ tremor_oggpack_buffer *b,int n,int point);
+extern long vorbis_book_decodev_set(codebook *book, tremor_ogg_int32_t *a,
+ tremor_oggpack_buffer *b,int n,int point);
+extern long vorbis_book_decodev_add(codebook *book, tremor_ogg_int32_t *a,
+ tremor_oggpack_buffer *b,int n,int point);
+extern long vorbis_book_decodevv_add(codebook *book, tremor_ogg_int32_t **a,
long off,int ch,
- oggpack_buffer *b,int n,int point);
+ tremor_oggpack_buffer *b,int n,int point);
extern int _ilog(unsigned int v);
diff --git a/lib/tremor/codec_internal.h b/lib/tremor/codec_internal.h
index 3ca7f547..f9a768bb 100644
--- a/lib/tremor/codec_internal.h
+++ b/lib/tremor/codec_internal.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -18,36 +18,149 @@
#ifndef _V_CODECI_H_
#define _V_CODECI_H_
+#define CHUNKSIZE 1024
+
#include "codebook.h"
+#include "ivorbiscodec.h"
+
+#define VI_TRANSFORMB 1
+#define VI_WINDOWB 1
+#define VI_TIMEB 1
+#define VI_FLOORB 2
+#define VI_RESB 3
+#define VI_MAPB 1
-typedef void vorbis_look_mapping;
-typedef void vorbis_look_floor;
-typedef void vorbis_look_residue;
-typedef void vorbis_look_transform;
+typedef void vorbis_info_floor;
+
+/* vorbis_dsp_state buffers the current vorbis audio
+ analysis/synthesis state. The DSP state belongs to a specific
+ logical bitstream ****************************************************/
+struct vorbis_dsp_state{
+ vorbis_info *vi;
+ tremor_oggpack_buffer opb;
+
+ tremor_ogg_int32_t **work;
+ tremor_ogg_int32_t **mdctright;
+ int out_begin;
+ int out_end;
+
+ long lW;
+ long W;
+
+ tremor_ogg_int64_t granulepos;
+ tremor_ogg_int64_t sequence;
+ tremor_ogg_int64_t sample_count;
+
+};
+
+
+/* Floor backend generic *****************************************/
+
+extern vorbis_info_floor *floor0_info_unpack(vorbis_info *,tremor_oggpack_buffer *);
+extern void floor0_free_info(vorbis_info_floor *);
+extern int floor0_memosize(vorbis_info_floor *);
+extern tremor_ogg_int32_t *floor0_inverse1(struct vorbis_dsp_state *,
+ vorbis_info_floor *,tremor_ogg_int32_t *);
+extern int floor0_inverse2 (struct vorbis_dsp_state *,vorbis_info_floor *,
+ tremor_ogg_int32_t *buffer,tremor_ogg_int32_t *);
+
+extern vorbis_info_floor *floor1_info_unpack(vorbis_info *,tremor_oggpack_buffer *);
+extern void floor1_free_info(vorbis_info_floor *);
+extern int floor1_memosize(vorbis_info_floor *);
+extern tremor_ogg_int32_t *floor1_inverse1(struct vorbis_dsp_state *,
+ vorbis_info_floor *,tremor_ogg_int32_t *);
+extern int floor1_inverse2 (struct vorbis_dsp_state *,vorbis_info_floor *,
+ tremor_ogg_int32_t *buffer,tremor_ogg_int32_t *);
+
+typedef struct{
+ int order;
+ long rate;
+ long barkmap;
+
+ int ampbits;
+ int ampdB;
+
+ int numbooks; /* <= 16 */
+ char books[16];
+
+} vorbis_info_floor0;
+
+typedef struct{
+ char class_dim; /* 1 to 8 */
+ char class_subs; /* 0,1,2,3 (bits: 1<<n poss) */
+ unsigned char class_book; /* subs ^ dim entries */
+ unsigned char class_subbook[8]; /* [VIF_CLASS][subs] */
+} floor1class;
+
+typedef struct{
+ floor1class *class; /* [VIF_CLASS] */
+ char *partitionclass; /* [VIF_PARTS]; 0 to 15 */
+ tremor_ogg_uint16_t *postlist; /* [VIF_POSIT+2]; first two implicit */
+ char *forward_index; /* [VIF_POSIT+2]; */
+ char *hineighbor; /* [VIF_POSIT]; */
+ char *loneighbor; /* [VIF_POSIT]; */
+
+ int partitions; /* 0 to 31 */
+ int posts;
+ int mult; /* 1 2 3 or 4 */
+
+} vorbis_info_floor1;
+
+/* Residue backend generic *****************************************/
+
+typedef struct vorbis_info_residue{
+ int type;
+ unsigned char *stagemasks;
+ unsigned char *stagebooks;
+
+/* block-partitioned VQ coded straight residue */
+ long begin;
+ long end;
+
+ /* first stage (lossless partitioning) */
+ int grouping; /* group n vectors per partition */
+ char partitions; /* possible codebooks for a partition */
+ unsigned char groupbook; /* huffbook for partitioning */
+ char stages;
+} vorbis_info_residue;
+
+extern void res_clear_info(vorbis_info_residue *info);
+extern int res_unpack(vorbis_info_residue *info,
+ vorbis_info *vi,tremor_oggpack_buffer *opb);
+extern int res_inverse(vorbis_dsp_state *,vorbis_info_residue *info,
+ tremor_ogg_int32_t **in,int *nonzero,int ch);
/* mode ************************************************************/
typedef struct {
- int blockflag;
- int windowtype;
- int transformtype;
- int mapping;
+ unsigned char blockflag;
+ unsigned char mapping;
} vorbis_info_mode;
-typedef void vorbis_info_floor;
-typedef void vorbis_info_residue;
-typedef void vorbis_info_mapping;
+/* Mapping backend generic *****************************************/
+typedef struct coupling_step{
+ unsigned char mag;
+ unsigned char ang;
+} coupling_step;
-typedef struct private_state {
- /* local lookup storage */
- const void *window[2];
+typedef struct submap{
+ char floor;
+ char residue;
+} submap;
- /* backend lookups are tied to the mode, not the backend or naked mapping */
- int modebits;
- vorbis_look_mapping **mode;
+typedef struct vorbis_info_mapping{
+ int submaps;
+
+ unsigned char *chmuxlist;
+ submap *submaplist;
- ogg_int64_t sample_count;
+ int coupling_steps;
+ coupling_step *coupling;
+} vorbis_info_mapping;
-} private_state;
+extern int mapping_info_unpack(vorbis_info_mapping *,vorbis_info *,
+ tremor_oggpack_buffer *);
+extern void mapping_clear_info(vorbis_info_mapping *);
+extern int mapping_inverse(struct vorbis_dsp_state *,vorbis_info_mapping *);
/* codec_setup_info contains all the setup information specific to the
specific compression/decompression mode in progress (eg,
@@ -69,24 +182,32 @@ typedef struct codec_setup_info {
int modes;
int maps;
- int times;
int floors;
int residues;
int books;
- vorbis_info_mode *mode_param[64];
- int map_type[64];
- vorbis_info_mapping *map_param[64];
- int time_type[64];
- int floor_type[64];
- vorbis_info_floor *floor_param[64];
- int residue_type[64];
- vorbis_info_residue *residue_param[64];
- static_codebook *book_param[256];
- codebook *fullbooks;
-
- int passlimit[32]; /* iteration limit per couple/quant pass */
- int coupling_passes;
+ vorbis_info_mode *mode_param;
+ vorbis_info_mapping *map_param;
+ char *floor_type;
+ vorbis_info_floor **floor_param;
+ vorbis_info_residue *residue_param;
+ codebook *book_param;
+
} codec_setup_info;
+extern vorbis_dsp_state *vorbis_dsp_create(vorbis_info *vi);
+extern void vorbis_dsp_destroy(vorbis_dsp_state *v);
+extern int vorbis_dsp_headerin(vorbis_info *vi,vorbis_comment *vc,
+ tremor_ogg_packet *op);
+
+extern int vorbis_dsp_restart(vorbis_dsp_state *v);
+extern int vorbis_dsp_synthesis(vorbis_dsp_state *vd,
+ tremor_ogg_packet *op,int decodep);
+extern int vorbis_dsp_pcmout(vorbis_dsp_state *v,
+ tremor_ogg_int16_t *pcm,int samples);
+extern int vorbis_dsp_read(vorbis_dsp_state *v,int samples);
+extern long vorbis_packet_blocksize(vorbis_info *vi,tremor_ogg_packet *op);
+
+
+
#endif
diff --git a/lib/tremor/config_types.h b/lib/tremor/config_types.h
index 1fdcb27f..a8873564 100644
--- a/lib/tremor/config_types.h
+++ b/lib/tremor/config_types.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -17,9 +17,10 @@
#ifndef _OS_CVTYPES_H
#define _OS_CVTYPES_H
-typedef long long ogg_int64_t;
-typedef int ogg_int32_t;
-typedef unsigned int ogg_uint32_t;
-typedef short ogg_int16_t;
+typedef long long tremor_ogg_int64_t;
+typedef int tremor_ogg_int32_t;
+typedef unsigned int tremor_ogg_uint32_t;
+typedef short tremor_ogg_int16_t;
+typedef unsigned short tremor_ogg_uint16_t;
#endif
diff --git a/lib/tremor/configure.in b/lib/tremor/configure.in
index e7f56900..a247f79c 100644
--- a/lib/tremor/configure.in
+++ b/lib/tremor/configure.in
@@ -51,7 +51,7 @@ if test -z "$GCC"; then
arm-*-*)
DEBUG="-g -D_ARM_ASSEM_"
CFLAGS="-O -D_ARM_ASSEM_"
- PROFILE="-p -g -O -D_ARM_ASSEM_" ;;
+ PROFILE="-p -g -O -D_ARM_ASSEM" ;;
*)
DEBUG="-g"
CFLAGS="-O"
@@ -61,12 +61,12 @@ else
case $host in
arm-*-*)
- DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char -D_ARM_ASSEM_"
- CFLAGS="-O2 -D_ARM_ASSEM_ -fsigned-char"
- PROFILE="-W -pg -g -O2 -D_ARM_ASSEM_ -fsigned-char -fno-inline-functions";;
+ DEBUG="-g -Wall -W -D__NO_MATH_INLINES -fsigned-char -D_ARM_ASSEM_"
+ CFLAGS="-O2 -Wall -D_ARM_ASSEM_ -fsigned-char"
+ PROFILE="-Wall -pg -g -O2 -D_ARM_ASSEM_ -fsigned-char -fno-inline-functions";;
*)
- DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char"
+ DEBUG="-g -Wall -W -D__NO_MATH_INLINES -fsigned-char"
CFLAGS="-O2 -Wall -fsigned-char"
PROFILE="-Wall -pg -g -O2 -fsigned-char -fno-inline-functions";;
esac
@@ -93,6 +93,12 @@ AC_ARG_ENABLE(
CFLAGS="$CFLAGS -D_LOW_ACCURACY_"
)
+AC_ARG_ENABLE(
+ 64kHz-limit,
+ [ --enable-64kHz-limit limit playback ability to <64kHz files],
+ CFLAGS="$CFLAGS -DLIMIT_TO_64kHz"
+)
+
dnl --------------------------------------------------
dnl Check for headers
dnl --------------------------------------------------
@@ -106,27 +112,6 @@ dnl --------------------------------------------------
dnl none
dnl --------------------------------------------------
-dnl Check for libraries
-dnl --------------------------------------------------
-
-PKG_PROG_PKG_CONFIG
-
-HAVE_OGG=no
-if test "x$PKG_CONFIG" != "x"
-then
- PKG_CHECK_MODULES(OGG, ogg >= 1.0, HAVE_OGG=yes, HAVE_OGG=no)
-fi
-if test "x$HAVE_OGG" = "xno"
-then
- dnl fall back to the old school test
- XIPH_PATH_OGG(, AC_MSG_ERROR(must have Ogg installed!))
- libs_save=$LIBS
- LIBS="$OGG_LIBS"
- AC_CHECK_FUNC(oggpack_writealign, , AC_MSG_ERROR(Ogg >= 1.0 required !))
- LIBS=$libs_save
-fi
-
-dnl --------------------------------------------------
dnl Check for library functions
dnl --------------------------------------------------
diff --git a/lib/tremor/dsp.c b/lib/tremor/dsp.c
new file mode 100644
index 00000000..35a82d66
--- /dev/null
+++ b/lib/tremor/dsp.c
@@ -0,0 +1,298 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: PCM data vector blocking, windowing and dis/reassembly
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include "tremor_ogg.h"
+#include "mdct.h"
+#include "ivorbiscodec.h"
+#include "codec_internal.h"
+#include "misc.h"
+#include "window_lookup.h"
+
+int vorbis_dsp_restart(vorbis_dsp_state *v){
+ if(!v)return -1;
+ {
+ vorbis_info *vi=v->vi;
+ codec_setup_info *ci;
+
+ if(!vi)return -1;
+ ci=vi->codec_setup;
+ if(!ci)return -1;
+
+ v->out_end=-1;
+ v->out_begin=-1;
+
+ v->granulepos=-1;
+ v->sequence=-1;
+ v->sample_count=-1;
+ }
+ return 0;
+}
+
+vorbis_dsp_state *vorbis_dsp_create(vorbis_info *vi){
+ int i;
+
+ vorbis_dsp_state *v=_tremor_ogg_calloc(1,sizeof(*v));
+ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+
+ v->vi=vi;
+
+ v->work=(tremor_ogg_int32_t **)_tremor_ogg_malloc(vi->channels*sizeof(*v->work));
+ v->mdctright=(tremor_ogg_int32_t **)_tremor_ogg_malloc(vi->channels*sizeof(*v->mdctright));
+ for(i=0;i<vi->channels;i++){
+ v->work[i]=(tremor_ogg_int32_t *)_tremor_ogg_calloc(1,(ci->blocksizes[1]>>1)*
+ sizeof(*v->work[i]));
+ v->mdctright[i]=(tremor_ogg_int32_t *)_tremor_ogg_calloc(1,(ci->blocksizes[1]>>2)*
+ sizeof(*v->mdctright[i]));
+ }
+
+ v->lW=0; /* previous window size */
+ v->W=0; /* current window size */
+
+ vorbis_dsp_restart(v);
+ return v;
+}
+
+void vorbis_dsp_destroy(vorbis_dsp_state *v){
+ int i;
+ if(v){
+ vorbis_info *vi=v->vi;
+
+ if(v->work){
+ for(i=0;i<vi->channels;i++)
+ if(v->work[i])_tremor_ogg_free(v->work[i]);
+ _tremor_ogg_free(v->work);
+ }
+ if(v->mdctright){
+ for(i=0;i<vi->channels;i++)
+ if(v->mdctright[i])_tremor_ogg_free(v->mdctright[i]);
+ _tremor_ogg_free(v->mdctright);
+ }
+
+ _tremor_ogg_free(v);
+ }
+}
+
+static LOOKUP_T *_vorbis_window(int left){
+ switch(left){
+ case 32:
+ return vwin64;
+ case 64:
+ return vwin128;
+ case 128:
+ return vwin256;
+ case 256:
+ return vwin512;
+ case 512:
+ return vwin1024;
+ case 1024:
+ return vwin2048;
+ case 2048:
+ return vwin4096;
+#ifndef LIMIT_TO_64kHz
+ case 4096:
+ return vwin8192;
+#endif
+ default:
+ return(0);
+ }
+}
+
+/* pcm==0 indicates we just want the pending samples, no more */
+int vorbis_dsp_pcmout(vorbis_dsp_state *v,tremor_ogg_int16_t *pcm,int samples){
+ vorbis_info *vi=v->vi;
+ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+ if(v->out_begin>-1 && v->out_begin<v->out_end){
+ int n=v->out_end-v->out_begin;
+ if(pcm){
+ int i;
+ if(n>samples)n=samples;
+ for(i=0;i<vi->channels;i++)
+ mdct_unroll_lap(ci->blocksizes[0],ci->blocksizes[1],
+ v->lW,v->W,v->work[i],v->mdctright[i],
+ _vorbis_window(ci->blocksizes[0]>>1),
+ _vorbis_window(ci->blocksizes[1]>>1),
+ pcm+i,vi->channels,
+ v->out_begin,v->out_begin+n);
+ }
+ return(n);
+ }
+ return(0);
+}
+
+int vorbis_dsp_read(vorbis_dsp_state *v,int s){
+ if(s && v->out_begin+s>v->out_end)return(OV_EINVAL);
+ v->out_begin+=s;
+ return(0);
+}
+
+long vorbis_packet_blocksize(vorbis_info *vi,tremor_ogg_packet *op){
+ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+ tremor_oggpack_buffer opb;
+ int mode;
+ int modebits=0;
+ int v=ci->modes;
+
+ tremor_oggpack_readinit(&opb,op->packet);
+
+ /* Check the packet type */
+ if(tremor_oggpack_read(&opb,1)!=0){
+ /* Oops. This is not an audio data packet */
+ return(OV_ENOTAUDIO);
+ }
+
+ while(v>1){
+ modebits++;
+ v>>=1;
+ }
+
+ /* read our mode and pre/post windowsize */
+ mode=tremor_oggpack_read(&opb,modebits);
+ if(mode==-1)return(OV_EBADPACKET);
+ return(ci->blocksizes[ci->mode_param[mode].blockflag]);
+}
+
+
+static int ilog(tremor_ogg_uint32_t v){
+ int ret=0;
+ if(v)--v;
+ while(v){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+int vorbis_dsp_synthesis(vorbis_dsp_state *vd,tremor_ogg_packet *op,int decodep){
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+ int mode,i;
+
+ tremor_oggpack_readinit(&vd->opb,op->packet);
+
+ /* Check the packet type */
+ if(tremor_oggpack_read(&vd->opb,1)!=0){
+ /* Oops. This is not an audio data packet */
+ return OV_ENOTAUDIO ;
+ }
+
+ /* read our mode and pre/post windowsize */
+ mode=tremor_oggpack_read(&vd->opb,ilog(ci->modes));
+ if(mode==-1 || mode>=ci->modes) return OV_EBADPACKET;
+
+ /* shift information we still need from last window */
+ vd->lW=vd->W;
+ vd->W=ci->mode_param[mode].blockflag;
+ for(i=0;i<vi->channels;i++)
+ mdct_shift_right(ci->blocksizes[vd->lW],vd->work[i],vd->mdctright[i]);
+
+ if(vd->W){
+ int temp;
+ tremor_oggpack_read(&vd->opb,1);
+ temp=tremor_oggpack_read(&vd->opb,1);
+ if(temp==-1) return OV_EBADPACKET;
+ }
+
+ /* packet decode and portions of synthesis that rely on only this block */
+ if(decodep){
+ mapping_inverse(vd,ci->map_param+ci->mode_param[mode].mapping);
+
+ if(vd->out_begin==-1){
+ vd->out_begin=0;
+ vd->out_end=0;
+ }else{
+ vd->out_begin=0;
+ vd->out_end=ci->blocksizes[vd->lW]/4+ci->blocksizes[vd->W]/4;
+ }
+ }
+
+ /* track the frame number... This is for convenience, but also
+ making sure our last packet doesn't end with added padding.
+
+ This is not foolproof! It will be confused if we begin
+ decoding at the last page after a seek or hole. In that case,
+ we don't have a starting point to judge where the last frame
+ is. For this reason, vorbisfile will always try to make sure
+ it reads the last two marked pages in proper sequence */
+
+ /* if we're out of sequence, dump granpos tracking until we sync back up */
+ if(vd->sequence==-1 || vd->sequence+1 != op->packetno-3){
+ /* out of sequence; lose count */
+ vd->granulepos=-1;
+ vd->sample_count=-1;
+ }
+
+ vd->sequence=op->packetno;
+ vd->sequence=vd->sequence-3;
+
+ if(vd->sample_count==-1){
+ vd->sample_count=0;
+ }else{
+ vd->sample_count+=
+ ci->blocksizes[vd->lW]/4+ci->blocksizes[vd->W]/4;
+ }
+
+ if(vd->granulepos==-1){
+ if(op->granulepos!=-1){ /* only set if we have a
+ position to set to */
+
+ vd->granulepos=op->granulepos;
+
+ /* is this a short page? */
+ if(vd->sample_count>vd->granulepos){
+ /* corner case; if this is both the first and last audio page,
+ then spec says the end is cut, not beginning */
+ if(op->e_o_s){
+ /* trim the end */
+ /* no preceeding granulepos; assume we started at zero (we'd
+ have to in a short single-page stream) */
+ /* granulepos could be -1 due to a seek, but that would result
+ in a long coun t, not short count */
+
+ vd->out_end-=vd->sample_count-vd->granulepos;
+ }else{
+ /* trim the beginning */
+ vd->out_begin+=vd->sample_count-vd->granulepos;
+ if(vd->out_begin>vd->out_end)
+ vd->out_begin=vd->out_end;
+ }
+
+ }
+
+ }
+ }else{
+ vd->granulepos+=
+ ci->blocksizes[vd->lW]/4+ci->blocksizes[vd->W]/4;
+ if(op->granulepos!=-1 && vd->granulepos!=op->granulepos){
+
+ if(vd->granulepos>op->granulepos){
+ long extra=vd->granulepos-op->granulepos;
+
+ if(extra)
+ if(op->e_o_s){
+ /* partial last frame. Strip the extra samples off */
+ vd->out_end-=extra;
+ } /* else {Shouldn't happen *unless* the bitstream is out of
+ spec. Either way, believe the bitstream } */
+ } /* else {Shouldn't happen *unless* the bitstream is out of
+ spec. Either way, believe the bitstream } */
+ vd->granulepos=op->granulepos;
+ }
+ }
+
+ return(0);
+}
diff --git a/lib/tremor/floor0.c b/lib/tremor/floor0.c
index 964383ef..9e4a1a30 100644
--- a/lib/tremor/floor0.c
+++ b/lib/tremor/floor0.c
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -18,26 +18,15 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
-#include <ogg/ogg.h>
+#include "tremor_ogg.h"
#include "ivorbiscodec.h"
#include "codec_internal.h"
-#include "registry.h"
#include "codebook.h"
#include "misc.h"
-#include "block.h"
+#include "os.h"
#define LSP_FRACBITS 14
-
-typedef struct {
- long n;
- int ln;
- int m;
- int *linearmap;
-
- vorbis_info_floor0 *vi;
- ogg_int32_t *lsp_look;
-
-} vorbis_look_floor0;
+extern const tremor_ogg_int32_t FLOOR_fromdB_LOOKUP[];
/*************** LSP decode ********************/
@@ -48,7 +37,7 @@ typedef struct {
returns in m.8 format */
static long ADJUST_SQRT2[2]={8192,5792};
-STIN ogg_int32_t vorbis_invsqlook_i(long a,long e){
+static inline tremor_ogg_int32_t vorbis_invsqlook_i(long a,long e){
long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1);
long d=a&INVSQ_LOOKUP_I_MASK; /* 0.10 */
long val=INVSQ_LOOKUP_I[i]- /* 1.16 */
@@ -60,60 +49,60 @@ STIN ogg_int32_t vorbis_invsqlook_i(long a,long e){
/* interpolated lookup based fromdB function, domain -140dB to 0dB only */
/* a is in n.12 format */
-STIN ogg_int32_t vorbis_fromdBlook_i(long a){
- int i=(-a)>>(12-FROMdB2_SHIFT);
- if(i<0) return 0x7fffffff;
- if(i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))return 0;
-
- return FROMdB_LOOKUP[i>>FROMdB_SHIFT] * FROMdB2_LOOKUP[i&FROMdB2_MASK];
+#ifdef _LOW_ACCURACY_
+static inline tremor_ogg_int32_t vorbis_fromdBlook_i(long a){
+ if(a>0) return 0x7fffffff;
+ if(a<(-140<<12)) return 0;
+ return FLOOR_fromdB_LOOKUP[((a+140)*467)>>20]<<9;
+}
+#else
+static inline tremor_ogg_int32_t vorbis_fromdBlook_i(long a){
+ if(a>0) return 0x7fffffff;
+ if(a<(-140<<12)) return 0;
+ return FLOOR_fromdB_LOOKUP[((a+(140<<12))*467)>>20];
}
+#endif
/* interpolated lookup based cos function, domain 0 to PI only */
/* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
-STIN ogg_int32_t vorbis_coslook_i(long a){
+static inline tremor_ogg_int32_t vorbis_coslook_i(long a){
int i=a>>COS_LOOKUP_I_SHIFT;
int d=a&COS_LOOKUP_I_MASK;
return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
COS_LOOKUP_I_SHIFT);
}
-/* interpolated lookup based cos function */
+/* interpolated half-wave lookup based cos function */
/* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */
-STIN ogg_int32_t vorbis_coslook2_i(long a){
- a=a&0x1ffff;
-
- if(a>0x10000)a=0x20000-a;
- {
- int i=a>>COS_LOOKUP_I_SHIFT;
- int d=a&COS_LOOKUP_I_MASK;
- a=((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
- d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
- (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
- }
-
- return(a);
+static inline tremor_ogg_int32_t vorbis_coslook2_i(long a){
+ int i=a>>COS_LOOKUP_I_SHIFT;
+ int d=a&COS_LOOKUP_I_MASK;
+ return ((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
+ d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
+ (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
}
-static const int barklook[28]={
- 0,100,200,301, 405,516,635,766,
- 912,1077,1263,1476, 1720,2003,2333,2721,
- 3184,3742,4428,5285, 6376,7791,9662,12181,
- 15624,20397,27087,36554
+static const tremor_ogg_uint16_t barklook[54]={
+ 0,51,102,154, 206,258,311,365,
+ 420,477,535,594, 656,719,785,854,
+ 926,1002,1082,1166, 1256,1352,1454,1564,
+ 1683,1812,1953,2107, 2276,2463,2670,2900,
+ 3155,3440,3756,4106, 4493,4919,5387,5901,
+ 6466,7094,7798,8599, 9528,10623,11935,13524,
+ 15453,17775,20517,23667, 27183,31004
};
/* used in init only; interpolate the long way */
-STIN ogg_int32_t toBARK(int n){
+static inline tremor_ogg_int32_t toBARK(int n){
int i;
- for(i=0;i<27;i++)
+ for(i=0;i<54;i++)
if(n>=barklook[i] && n<barklook[i+1])break;
- if(i==27){
- return 27<<15;
+ if(i==54){
+ return 54<<14;
}else{
- int gap=barklook[i+1]-barklook[i];
- int del=n-barklook[i];
-
- return((i<<15)+((del<<15)/gap));
+ return (i<<14)+(((n-barklook[i])*
+ ((1UL<<31)/(barklook[i+1]-barklook[i])))>>17);
}
}
@@ -133,11 +122,11 @@ static const unsigned char MLOOP_2[64]={
static const unsigned char MLOOP_3[8]={0,1,2,2,3,3,3,3};
-void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
- ogg_int32_t *lsp,int m,
- ogg_int32_t amp,
- ogg_int32_t ampoffset,
- ogg_int32_t *icos){
+void vorbis_lsp_to_curve(tremor_ogg_int32_t *curve,int n,int ln,
+ tremor_ogg_int32_t *lsp,int m,
+ tremor_ogg_int32_t amp,
+ tremor_ogg_int32_t ampoffset,
+ tremor_ogg_int32_t nyq){
/* 0 <= m < 256 */
@@ -145,13 +134,34 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
int i;
int ampoffseti=ampoffset*4096;
int ampi=amp;
- ogg_int32_t *ilsp=(ogg_int32_t *)alloca(m*sizeof(*ilsp));
+ tremor_ogg_int32_t *ilsp=(tremor_ogg_int32_t *)alloca(m*sizeof(*ilsp));
+
+ tremor_ogg_uint32_t inyq= (1UL<<31) / toBARK(nyq);
+ tremor_ogg_uint32_t imap= (1UL<<31) / ln;
+ tremor_ogg_uint32_t tBnyq1 = toBARK(nyq)<<1;
+
+ /* Besenham for frequency scale to avoid a division */
+ int f=0;
+ int fdx=n;
+ int fbase=nyq/fdx;
+ int ferr=0;
+ int fdy=nyq-fbase*fdx;
+ int map=0;
+
+#ifdef _LOW_ACCURACY_
+ tremor_ogg_uint32_t nextbark=((tBnyq1<<11)/ln)>>12;
+#else
+ tremor_ogg_uint32_t nextbark=MULT31(imap>>1,tBnyq1);
+#endif
+ int nextf=barklook[nextbark>>14]+(((nextbark&0x3fff)*
+ (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14);
+
/* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
for(i=0;i<m;i++){
#ifndef _LOW_ACCURACY_
- ogg_int32_t val=MULT32(lsp[i],0x517cc2);
+ tremor_ogg_int32_t val=MULT32(lsp[i],0x517cc2);
#else
- ogg_int32_t val=((lsp[i]>>10)*0x517d)>>14;
+ tremor_ogg_int32_t val=((lsp[i]>>10)*0x517d)>>14;
#endif
/* safeguard against a malicious stream */
@@ -165,11 +175,14 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
i=0;
while(i<n){
- int j,k=map[i];
- ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
- ogg_uint32_t qi=46341;
- ogg_int32_t qexp=0,shift;
- ogg_int32_t wi=icos[k];
+ int j;
+ tremor_ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
+ tremor_ogg_uint32_t qi=46341;
+ tremor_ogg_int32_t qexp=0,shift;
+ tremor_ogg_int32_t wi;
+
+ wi=vorbis_coslook2_i((map*imap)>>15);
+
#ifdef _V_LSP_MATH_ASM
lsp_loop_asm(&qi,&pi,&qexp,ilsp,wi,m);
@@ -197,24 +210,22 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
#else
- j=1;
- if(m>1){
- qi*=labs(ilsp[0]-wi);
- pi*=labs(ilsp[1]-wi);
-
- for(j+=2;j<m;j+=2){
- if(!(shift=MLOOP_1[(pi|qi)>>25]))
- if(!(shift=MLOOP_2[(pi|qi)>>19]))
- shift=MLOOP_3[(pi|qi)>>16];
- qi=(qi>>shift)*labs(ilsp[j-1]-wi);
- pi=(pi>>shift)*labs(ilsp[j]-wi);
- qexp+=shift;
- }
+ qi*=labs(ilsp[0]-wi);
+ pi*=labs(ilsp[1]-wi);
+
+ for(j=3;j<m;j+=2){
+ if(!(shift=MLOOP_1[(pi|qi)>>25]))
+ if(!(shift=MLOOP_2[(pi|qi)>>19]))
+ shift=MLOOP_3[(pi|qi)>>16];
+
+ qi=(qi>>shift)*labs(ilsp[j-1]-wi);
+ pi=(pi>>shift)*labs(ilsp[j]-wi);
+ qexp+=shift;
}
if(!(shift=MLOOP_1[(pi|qi)>>25]))
if(!(shift=MLOOP_2[(pi|qi)>>19]))
shift=MLOOP_3[(pi|qi)>>16];
-
+
/* pi,qi normalized collectively, both tracked using qexp */
if(m&1){
@@ -282,54 +293,78 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
amp>>=9;
#endif
curve[i]= MULT31_SHIFT15(curve[i],amp);
- while(map[++i]==k) curve[i]= MULT31_SHIFT15(curve[i],amp);
- }
-}
-/*************** vorbis decode glue ************/
+ while(++i<n){
+
+ /* line plot to get new f */
+ ferr+=fdy;
+ if(ferr>=fdx){
+ ferr-=fdx;
+ f++;
+ }
+ f+=fbase;
+
+ if(f>=nextf)break;
-static void floor0_free_info(vorbis_info_floor *i){
- vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
- if(info){
- memset(info,0,sizeof(*info));
- _ogg_free(info);
+ curve[i]= MULT31_SHIFT15(curve[i],amp);
+ }
+
+ while(1){
+ map++;
+
+ if(map+1<ln){
+
+#ifdef _LOW_ACCURACY_
+ nextbark=((tBnyq1<<11)/ln*(map+1))>>12;
+#else
+ nextbark=MULT31((map+1)*(imap>>1),tBnyq1);
+#endif
+ nextf=barklook[nextbark>>14]+
+ (((nextbark&0x3fff)*
+ (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14);
+ if(f<=nextf)break;
+
+ }else{
+ nextf=9999999;
+ break;
+ }
+ }
+ if(map>=ln){
+ map=ln-1; /* guard against the approximation */
+ nextf=9999999;
+ }
}
}
-static void floor0_free_look(vorbis_look_floor *i){
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
- if(look){
+/*************** vorbis decode glue ************/
- if(look->linearmap)_ogg_free(look->linearmap);
- if(look->lsp_look)_ogg_free(look->lsp_look);
- memset(look,0,sizeof(*look));
- _ogg_free(look);
- }
+void floor0_free_info(vorbis_info_floor *i){
+ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
+ if(info)_tremor_ogg_free(info);
}
-static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
+vorbis_info_floor *floor0_info_unpack (vorbis_info *vi,tremor_oggpack_buffer *opb){
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
int j;
- vorbis_info_floor0 *info=(vorbis_info_floor0 *)_ogg_malloc(sizeof(*info));
- 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;
+ vorbis_info_floor0 *info=(vorbis_info_floor0 *)_tremor_ogg_malloc(sizeof(*info));
+ info->order=tremor_oggpack_read(opb,8);
+ info->rate=tremor_oggpack_read(opb,16);
+ info->barkmap=tremor_oggpack_read(opb,16);
+ info->ampbits=tremor_oggpack_read(opb,6);
+ info->ampdB=tremor_oggpack_read(opb,8);
+ info->numbooks=tremor_oggpack_read(opb,4)+1;
if(info->order<1)goto err_out;
if(info->rate<1)goto err_out;
if(info->barkmap<1)goto err_out;
- if(info->numbooks<1)goto err_out;
for(j=0;j<info->numbooks;j++){
- info->books[j]=oggpack_read(opb,8);
- if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
- if(ci->book_param[info->books[j]]->maptype==0)goto err_out;
- if(ci->book_param[info->books[j]]->dim<1)goto err_out;
+ info->books[j]=tremor_oggpack_read(opb,8);
+ if(info->books[j]>=ci->books)goto err_out;
}
+
+ if(tremor_oggpack_eop(opb))goto err_out;
return(info);
err_out:
@@ -337,74 +372,34 @@ static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
return(NULL);
}
-/* initialize Bark scale and normalization lookups. We could do this
- with static tables, but Vorbis allows a number of possible
- combinations, so it's best to do it computationally.
-
- The below is authoritative in terms of defining scale mapping.
- Note that the scale depends on the sampling rate as well as the
- linear block and mapping sizes */
-
-static vorbis_look_floor *floor0_look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
- vorbis_info_floor *i){
- int j;
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+int floor0_memosize(vorbis_info_floor *i){
vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)_ogg_calloc(1,sizeof(*look));
- look->m=info->order;
- look->n=ci->blocksizes[mi->blockflag]/2;
- look->ln=info->barkmap;
- look->vi=info;
-
- /* the mapping from a linear scale to a smaller bark scale is
- straightforward. We do *not* make sure that the linear mapping
- does not skip bark-scale bins; the decoder simply skips them and
- the encoder may do what it wishes in filling them. They're
- necessary in some mapping combinations to keep the scale spacing
- accurate */
- look->linearmap=(int *)_ogg_malloc((look->n+1)*sizeof(*look->linearmap));
- for(j=0;j<look->n;j++){
-
- int val=(look->ln*
- ((toBARK(info->rate/2*j/look->n)<<11)/toBARK(info->rate/2)))>>11;
-
- if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
- look->linearmap[j]=val;
- }
- look->linearmap[j]=-1;
-
- look->lsp_look=(ogg_int32_t *)_ogg_malloc(look->ln*sizeof(*look->lsp_look));
- for(j=0;j<look->ln;j++)
- look->lsp_look[j]=vorbis_coslook2_i(0x10000*j/look->ln);
-
- return look;
+ return info->order+1;
}
-static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
- vorbis_info_floor0 *info=look->vi;
+tremor_ogg_int32_t *floor0_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *i,
+ tremor_ogg_int32_t *lsp){
+ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
int j,k;
- int ampraw=oggpack_read(&vb->opb,info->ampbits);
+ int ampraw=tremor_oggpack_read(&vd->opb,info->ampbits);
if(ampraw>0){ /* also handles the -1 out of data case */
long maxval=(1<<info->ampbits)-1;
int amp=((ampraw*info->ampdB)<<4)/maxval;
- int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
+ int booknum=tremor_oggpack_read(&vd->opb,_ilog(info->numbooks));
if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
- codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
- codebook *b=ci->fullbooks+info->books[booknum];
- ogg_int32_t last=0;
- ogg_int32_t *lsp=(ogg_int32_t *)_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+1));
+ codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup;
+ codebook *b=ci->book_param+info->books[booknum];
+ tremor_ogg_int32_t last=0;
- if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m,-24)==-1)goto eop;
- for(j=0;j<look->m;){
- for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
+ if(vorbis_book_decodev_set(b,lsp,&vd->opb,info->order,-24)==-1)goto eop;
+ for(j=0;j<info->order;){
+ for(k=0;j<info->order && k<b->dim;k++,j++)lsp[j]+=last;
last=lsp[j-1];
}
- lsp[look->m]=amp;
+ lsp[info->order]=amp;
return(lsp);
}
}
@@ -412,28 +407,21 @@ static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
return(NULL);
}
-static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
- void *memo,ogg_int32_t *out){
- vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
- vorbis_info_floor0 *info=look->vi;
+int floor0_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *i,
+ tremor_ogg_int32_t *lsp,tremor_ogg_int32_t *out){
+ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
+ codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup;
- if(memo){
- ogg_int32_t *lsp=(ogg_int32_t *)memo;
- ogg_int32_t amp=lsp[look->m];
+ if(lsp){
+ tremor_ogg_int32_t amp=lsp[info->order];
/* take the coefficients back to a spectral envelope curve */
- vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
- lsp,look->m,amp,info->ampdB,look->lsp_look);
+ vorbis_lsp_to_curve(out,ci->blocksizes[vd->W]/2,info->barkmap,
+ lsp,info->order,amp,info->ampdB,
+ info->rate>>1);
return(1);
}
- memset(out,0,sizeof(*out)*look->n);
+ memset(out,0,sizeof(*out)*ci->blocksizes[vd->W]/2);
return(0);
}
-/* export hooks */
-vorbis_func_floor floor0_exportbundle={
- &floor0_unpack,&floor0_look,&floor0_free_info,
- &floor0_free_look,&floor0_inverse1,&floor0_inverse2
-};
-
-
diff --git a/lib/tremor/floor1.c b/lib/tremor/floor1.c
index e63ae9fb..1dc5f357 100644
--- a/lib/tremor/floor1.c
+++ b/lib/tremor/floor1.c
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -18,44 +18,29 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
-#include <ogg/ogg.h>
+#include "tremor_ogg.h"
#include "ivorbiscodec.h"
#include "codec_internal.h"
-#include "registry.h"
#include "codebook.h"
#include "misc.h"
-#include "block.h"
+extern const tremor_ogg_int32_t FLOOR_fromdB_LOOKUP[];
#define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
-
-typedef struct {
- int forward_index[VIF_POSIT+2];
-
- int hineighbor[VIF_POSIT];
- int loneighbor[VIF_POSIT];
- int posts;
-
- int n;
- int quant_q;
- vorbis_info_floor1 *vi;
-
-} vorbis_look_floor1;
+#define VIF_POSIT 63
/***********************************************/
-static void floor1_free_info(vorbis_info_floor *i){
+void floor1_free_info(vorbis_info_floor *i){
vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
if(info){
+ if(info->class)_tremor_ogg_free(info->class);
+ if(info->partitionclass)_tremor_ogg_free(info->partitionclass);
+ if(info->postlist)_tremor_ogg_free(info->postlist);
+ if(info->forward_index)_tremor_ogg_free(info->forward_index);
+ if(info->hineighbor)_tremor_ogg_free(info->hineighbor);
+ if(info->loneighbor)_tremor_ogg_free(info->loneighbor);
memset(info,0,sizeof(*info));
- _ogg_free(info);
- }
-}
-
-static void floor1_free_look(vorbis_look_floor *i){
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
- if(look){
- memset(look,0,sizeof(*look));
- _ogg_free(look);
+ _tremor_ogg_free(info);
}
}
@@ -68,143 +53,131 @@ static int ilog(unsigned int v){
return(ret);
}
-static int icomp(const void *a,const void *b){
- return(**(int **)a-**(int **)b);
+static void vorbis_mergesort(char *index,tremor_ogg_uint16_t *vals,tremor_ogg_uint16_t n){
+ tremor_ogg_uint16_t i,j;
+ char *temp,*A=index,*B=_tremor_ogg_malloc(n*sizeof(*B));
+
+ for(i=1;i<n;i<<=1){
+ for(j=0;j+i<n;){
+ int k1=j;
+ int mid=j+i;
+ int k2=mid;
+ int end=(j+i*2<n?j+i*2:n);
+ while(k1<mid && k2<end){
+ if(vals[A[k1]]<vals[A[k2]])
+ B[j++]=A[k1++];
+ else
+ B[j++]=A[k2++];
+ }
+ while(k1<mid) B[j++]=A[k1++];
+ while(k2<end) B[j++]=A[k2++];
+ }
+ for(;j<n;j++)B[j]=A[j];
+ temp=A;A=B;B=temp;
+ }
+
+ if(B==index){
+ for(j=0;j<n;j++)B[j]=A[j];
+ _tremor_ogg_free(A);
+ }else
+ _tremor_ogg_free(B);
}
-static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
+
+vorbis_info_floor *floor1_info_unpack (vorbis_info *vi,tremor_oggpack_buffer *opb){
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
int j,k,count=0,maxclass=-1,rangebits;
-
- vorbis_info_floor1 *info=(vorbis_info_floor1 *)_ogg_calloc(1,sizeof(*info));
+
+ vorbis_info_floor1 *info=(vorbis_info_floor1 *)_tremor_ogg_calloc(1,sizeof(*info));
/* read partitions */
- info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
+ info->partitions=tremor_oggpack_read(opb,5); /* only 0 to 31 legal */
+ info->partitionclass=
+ (char *)_tremor_ogg_malloc(info->partitions*sizeof(*info->partitionclass));
for(j=0;j<info->partitions;j++){
- info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
- if(info->partitionclass[j]<0)goto err_out;
+ info->partitionclass[j]=tremor_oggpack_read(opb,4); /* only 0 to 15 legal */
if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
}
/* read partition classes */
+ info->class=
+ (floor1class *)_tremor_ogg_malloc((maxclass+1)*sizeof(*info->class));
for(j=0;j<maxclass+1;j++){
- info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
- info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
- if(info->class_subs[j]<0)
- goto err_out;
- if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
- if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
- goto err_out;
- for(k=0;k<(1<<info->class_subs[j]);k++){
- info->class_subbook[j][k]=oggpack_read(opb,8)-1;
- if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
- goto err_out;
+ info->class[j].class_dim=tremor_oggpack_read(opb,3)+1; /* 1 to 8 */
+ info->class[j].class_subs=tremor_oggpack_read(opb,2); /* 0,1,2,3 bits */
+ if(tremor_oggpack_eop(opb)<0) goto err_out;
+ if(info->class[j].class_subs)
+ info->class[j].class_book=tremor_oggpack_read(opb,8);
+ else
+ info->class[j].class_book=0;
+ if(info->class[j].class_book>=ci->books)goto err_out;
+ for(k=0;k<(1<<info->class[j].class_subs);k++){
+ info->class[j].class_subbook[k]=tremor_oggpack_read(opb,8)-1;
+ if(info->class[j].class_subbook[k]>=ci->books &&
+ info->class[j].class_subbook[k]!=0xff)goto err_out;
}
}
/* read the post list */
- info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
- rangebits=oggpack_read(opb,4);
- if(rangebits<0)goto err_out;
-
+ info->mult=tremor_oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
+ rangebits=tremor_oggpack_read(opb,4);
+
+ for(j=0,k=0;j<info->partitions;j++)
+ count+=info->class[info->partitionclass[j]].class_dim;
+ info->postlist=
+ (tremor_ogg_uint16_t *)_tremor_ogg_malloc((count+2)*sizeof(*info->postlist));
+ info->forward_index=
+ (char *)_tremor_ogg_malloc((count+2)*sizeof(*info->forward_index));
+ info->loneighbor=
+ (char *)_tremor_ogg_malloc(count*sizeof(*info->loneighbor));
+ info->hineighbor=
+ (char *)_tremor_ogg_malloc(count*sizeof(*info->hineighbor));
+
+ count=0;
for(j=0,k=0;j<info->partitions;j++){
- count+=info->class_dim[info->partitionclass[j]];
+ count+=info->class[info->partitionclass[j]].class_dim;
if(count>VIF_POSIT)goto err_out;
for(;k<count;k++){
- int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
- if(t<0 || t>=(1<<rangebits))
- goto err_out;
+ int t=info->postlist[k+2]=tremor_oggpack_read(opb,rangebits);
+ if(t>=(1<<rangebits))goto err_out;
}
}
+ if(tremor_oggpack_eop(opb))goto err_out;
info->postlist[0]=0;
info->postlist[1]=1<<rangebits;
-
- /* don't allow repeated values in post list as they'd result in
- zero-length segments */
- {
- int *sortpointer[VIF_POSIT+2];
- for(j=0;j<count+2;j++)sortpointer[j]=info->postlist+j;
- qsort(sortpointer,count+2,sizeof(*sortpointer),icomp);
-
- for(j=1;j<count+2;j++)
- if(*sortpointer[j-1]==*sortpointer[j])goto err_out;
- }
-
- return(info);
-
- err_out:
- floor1_free_info(info);
- return(NULL);
-}
-
-static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,vorbis_info_mode *mi,
- vorbis_info_floor *in){
-
- int *sortpointer[VIF_POSIT+2];
- vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)_ogg_calloc(1,sizeof(*look));
- int i,j,n=0;
-
- look->vi=info;
- look->n=info->postlist[1];
-
- /* we drop each position value in-between already decoded values,
- and use linear interpolation to predict each new value past the
- edges. The positions are read in the order of the position
- list... we precompute the bounding positions in the lookup. Of
- course, the neighbors can change (if a position is declined), but
- this is an initial mapping */
-
- for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
- n+=2;
- look->posts=n;
+ info->posts=count+2;
/* also store a sorted position index */
- for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
- qsort(sortpointer,n,sizeof(*sortpointer),icomp);
-
- /* points from sort order back to range number */
- for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
+ for(j=0;j<info->posts;j++)info->forward_index[j]=j;
+ vorbis_mergesort(info->forward_index,info->postlist,info->posts);
- /* quantize values to multiplier spec */
- switch(info->mult){
- case 1: /* 1024 -> 256 */
- look->quant_q=256;
- break;
- case 2: /* 1024 -> 128 */
- look->quant_q=128;
- break;
- case 3: /* 1024 -> 86 */
- look->quant_q=86;
- break;
- case 4: /* 1024 -> 64 */
- look->quant_q=64;
- break;
- }
-
/* discover our neighbors for decode where we don't use fit flags
(that would push the neighbors outward) */
- for(i=0;i<n-2;i++){
+ for(j=0;j<info->posts-2;j++){
int lo=0;
int hi=1;
int lx=0;
- int hx=look->n;
- int currentx=info->postlist[i+2];
- for(j=0;j<i+2;j++){
- int x=info->postlist[j];
+ int hx=info->postlist[1];
+ int currentx=info->postlist[j+2];
+ for(k=0;k<j+2;k++){
+ int x=info->postlist[k];
if(x>lx && x<currentx){
- lo=j;
+ lo=k;
lx=x;
}
if(x<hx && x>currentx){
- hi=j;
+ hi=k;
hx=x;
}
}
- look->loneighbor[i]=lo;
- look->hineighbor[i]=hi;
+ info->loneighbor[j]=lo;
+ info->hineighbor[j]=hi;
}
- return(look);
+ return(info);
+
+ err_out:
+ floor1_free_info(info);
+ return(NULL);
}
static int render_point(int x0,int x1,int y0,int y1,int x){
@@ -223,80 +196,7 @@ static int render_point(int x0,int x1,int y0,int y1,int x){
}
}
-#ifdef _LOW_ACCURACY_
-# define XdB(n) ((((n)>>8)+1)>>1)
-#else
-# define XdB(n) (n)
-#endif
-
-static const ogg_int32_t FLOOR_fromdB_LOOKUP[256]={
- XdB(0x000000e5), XdB(0x000000f4), XdB(0x00000103), XdB(0x00000114),
- XdB(0x00000126), XdB(0x00000139), XdB(0x0000014e), XdB(0x00000163),
- XdB(0x0000017a), XdB(0x00000193), XdB(0x000001ad), XdB(0x000001c9),
- XdB(0x000001e7), XdB(0x00000206), XdB(0x00000228), XdB(0x0000024c),
- XdB(0x00000272), XdB(0x0000029b), XdB(0x000002c6), XdB(0x000002f4),
- XdB(0x00000326), XdB(0x0000035a), XdB(0x00000392), XdB(0x000003cd),
- XdB(0x0000040c), XdB(0x00000450), XdB(0x00000497), XdB(0x000004e4),
- XdB(0x00000535), XdB(0x0000058c), XdB(0x000005e8), XdB(0x0000064a),
- XdB(0x000006b3), XdB(0x00000722), XdB(0x00000799), XdB(0x00000818),
- XdB(0x0000089e), XdB(0x0000092e), XdB(0x000009c6), XdB(0x00000a69),
- XdB(0x00000b16), XdB(0x00000bcf), XdB(0x00000c93), XdB(0x00000d64),
- XdB(0x00000e43), XdB(0x00000f30), XdB(0x0000102d), XdB(0x0000113a),
- XdB(0x00001258), XdB(0x0000138a), XdB(0x000014cf), XdB(0x00001629),
- XdB(0x0000179a), XdB(0x00001922), XdB(0x00001ac4), XdB(0x00001c82),
- XdB(0x00001e5c), XdB(0x00002055), XdB(0x0000226f), XdB(0x000024ac),
- XdB(0x0000270e), XdB(0x00002997), XdB(0x00002c4b), XdB(0x00002f2c),
- XdB(0x0000323d), XdB(0x00003581), XdB(0x000038fb), XdB(0x00003caf),
- XdB(0x000040a0), XdB(0x000044d3), XdB(0x0000494c), XdB(0x00004e10),
- XdB(0x00005323), XdB(0x0000588a), XdB(0x00005e4b), XdB(0x0000646b),
- XdB(0x00006af2), XdB(0x000071e5), XdB(0x0000794c), XdB(0x0000812e),
- XdB(0x00008993), XdB(0x00009283), XdB(0x00009c09), XdB(0x0000a62d),
- XdB(0x0000b0f9), XdB(0x0000bc79), XdB(0x0000c8b9), XdB(0x0000d5c4),
- XdB(0x0000e3a9), XdB(0x0000f274), XdB(0x00010235), XdB(0x000112fd),
- XdB(0x000124dc), XdB(0x000137e4), XdB(0x00014c29), XdB(0x000161bf),
- XdB(0x000178bc), XdB(0x00019137), XdB(0x0001ab4a), XdB(0x0001c70e),
- XdB(0x0001e4a1), XdB(0x0002041f), XdB(0x000225aa), XdB(0x00024962),
- XdB(0x00026f6d), XdB(0x000297f0), XdB(0x0002c316), XdB(0x0002f109),
- XdB(0x000321f9), XdB(0x00035616), XdB(0x00038d97), XdB(0x0003c8b4),
- XdB(0x000407a7), XdB(0x00044ab2), XdB(0x00049218), XdB(0x0004de23),
- XdB(0x00052f1e), XdB(0x0005855c), XdB(0x0005e135), XdB(0x00064306),
- XdB(0x0006ab33), XdB(0x00071a24), XdB(0x0007904b), XdB(0x00080e20),
- XdB(0x00089422), XdB(0x000922da), XdB(0x0009bad8), XdB(0x000a5cb6),
- XdB(0x000b091a), XdB(0x000bc0b1), XdB(0x000c8436), XdB(0x000d5471),
- XdB(0x000e3233), XdB(0x000f1e5f), XdB(0x001019e4), XdB(0x001125c1),
- XdB(0x00124306), XdB(0x001372d5), XdB(0x0014b663), XdB(0x00160ef7),
- XdB(0x00177df0), XdB(0x001904c1), XdB(0x001aa4f9), XdB(0x001c603d),
- XdB(0x001e384f), XdB(0x00202f0f), XdB(0x0022467a), XdB(0x002480b1),
- XdB(0x0026dff7), XdB(0x002966b3), XdB(0x002c1776), XdB(0x002ef4fc),
- XdB(0x0032022d), XdB(0x00354222), XdB(0x0038b828), XdB(0x003c67c2),
- XdB(0x004054ae), XdB(0x004482e8), XdB(0x0048f6af), XdB(0x004db488),
- XdB(0x0052c142), XdB(0x005821ff), XdB(0x005ddc33), XdB(0x0063f5b0),
- XdB(0x006a74a7), XdB(0x00715faf), XdB(0x0078bdce), XdB(0x0080967f),
- XdB(0x0088f1ba), XdB(0x0091d7f9), XdB(0x009b5247), XdB(0x00a56a41),
- XdB(0x00b02a27), XdB(0x00bb9ce2), XdB(0x00c7ce12), XdB(0x00d4ca17),
- XdB(0x00e29e20), XdB(0x00f15835), XdB(0x0101074b), XdB(0x0111bb4e),
- XdB(0x01238531), XdB(0x01367704), XdB(0x014aa402), XdB(0x016020a7),
- XdB(0x017702c3), XdB(0x018f6190), XdB(0x01a955cb), XdB(0x01c4f9cf),
- XdB(0x01e269a8), XdB(0x0201c33b), XdB(0x0223265a), XdB(0x0246b4ea),
- XdB(0x026c9302), XdB(0x0294e716), XdB(0x02bfda13), XdB(0x02ed9793),
- XdB(0x031e4e09), XdB(0x03522ee4), XdB(0x03896ed0), XdB(0x03c445e2),
- XdB(0x0402efd6), XdB(0x0445ac4b), XdB(0x048cbefc), XdB(0x04d87013),
- XdB(0x05290c67), XdB(0x057ee5ca), XdB(0x05da5364), XdB(0x063bb204),
- XdB(0x06a36485), XdB(0x0711d42b), XdB(0x0787710e), XdB(0x0804b299),
- XdB(0x088a17ef), XdB(0x0918287e), XdB(0x09af747c), XdB(0x0a50957e),
- XdB(0x0afc2f19), XdB(0x0bb2ef7f), XdB(0x0c759034), XdB(0x0d44d6ca),
- XdB(0x0e2195bc), XdB(0x0f0cad0d), XdB(0x10070b62), XdB(0x1111aeea),
- XdB(0x122da66c), XdB(0x135c120f), XdB(0x149e24d9), XdB(0x15f525b1),
- XdB(0x176270e3), XdB(0x18e7794b), XdB(0x1a85c9ae), XdB(0x1c3f06d1),
- XdB(0x1e14f07d), XdB(0x200963d7), XdB(0x221e5ccd), XdB(0x2455f870),
- XdB(0x26b2770b), XdB(0x29363e2b), XdB(0x2be3db5c), XdB(0x2ebe06b6),
- XdB(0x31c7a55b), XdB(0x3503ccd4), XdB(0x3875c5aa), XdB(0x3c210f44),
- XdB(0x4009632b), XdB(0x4432b8cf), XdB(0x48a149bc), XdB(0x4d59959e),
- XdB(0x52606733), XdB(0x57bad899), XdB(0x5d6e593a), XdB(0x6380b298),
- XdB(0x69f80e9a), XdB(0x70dafda8), XdB(0x78307d76), XdB(0x7fffffff),
-};
-
-static void render_line(int n, int x0,int x1,int y0,int y1,ogg_int32_t *d){
+static void render_line(int n,int x0,int x1,int y0,int y1,tremor_ogg_int32_t *d){
int dy=y1-y0;
int adx=x1-x0;
int ady=abs(dy);
@@ -324,42 +224,48 @@ static void render_line(int n, int x0,int x1,int y0,int y1,ogg_int32_t *d){
}
}
-static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
- vorbis_info_floor1 *info=look->vi;
- codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
+int floor1_memosize(vorbis_info_floor *i){
+ vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
+ return info->posts;
+}
+
+static int quant_look[4]={256,128,86,64};
+
+tremor_ogg_int32_t *floor1_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *in,
+ tremor_ogg_int32_t *fit_value){
+ vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
+ codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup;
int i,j,k;
- codebook *books=ci->fullbooks;
-
+ codebook *books=ci->book_param;
+ int quant_q=quant_look[info->mult-1];
+
/* unpack wrapped/predicted values from stream */
- if(oggpack_read(&vb->opb,1)==1){
- int *fit_value=(int *)_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
-
- fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
- fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
+ if(tremor_oggpack_read(&vd->opb,1)==1){
+ fit_value[0]=tremor_oggpack_read(&vd->opb,ilog(quant_q-1));
+ fit_value[1]=tremor_oggpack_read(&vd->opb,ilog(quant_q-1));
/* partition by partition */
/* partition by partition */
for(i=0,j=2;i<info->partitions;i++){
int classv=info->partitionclass[i];
- int cdim=info->class_dim[classv];
- int csubbits=info->class_subs[classv];
+ int cdim=info->class[classv].class_dim;
+ int csubbits=info->class[classv].class_subs;
int csub=1<<csubbits;
int cval=0;
/* decode the partition's first stage cascade value */
if(csubbits){
- cval=vorbis_book_decode(books+info->class_book[classv],&vb->opb);
+ cval=vorbis_book_decode(books+info->class[classv].class_book,&vd->opb);
if(cval==-1)goto eop;
}
for(k=0;k<cdim;k++){
- int book=info->class_subbook[classv][cval&(csub-1)];
+ int book=info->class[classv].class_subbook[cval&(csub-1)];
cval>>=csubbits;
- if(book>=0){
- if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
+ if(book!=0xff){
+ if((fit_value[j+k]=vorbis_book_decode(books+book,&vd->opb))==-1)
goto eop;
}else{
fit_value[j+k]=0;
@@ -369,13 +275,13 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
}
/* unwrap positive values and reconsitute via linear interpolation */
- for(i=2;i<look->posts;i++){
- int predicted=render_point(info->postlist[look->loneighbor[i-2]],
- info->postlist[look->hineighbor[i-2]],
- fit_value[look->loneighbor[i-2]],
- fit_value[look->hineighbor[i-2]],
+ for(i=2;i<info->posts;i++){
+ int predicted=render_point(info->postlist[info->loneighbor[i-2]],
+ info->postlist[info->hineighbor[i-2]],
+ fit_value[info->loneighbor[i-2]],
+ fit_value[info->hineighbor[i-2]],
info->postlist[i]);
- int hiroom=look->quant_q-predicted;
+ int hiroom=quant_q-predicted;
int loroom=predicted;
int room=(hiroom<loroom?hiroom:loroom)<<1;
int val=fit_value[i];
@@ -395,9 +301,9 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
}
}
- fit_value[i]=(val+predicted)&0x7fff;;
- fit_value[look->loneighbor[i-2]]&=0x7fff;
- fit_value[look->hineighbor[i-2]]&=0x7fff;
+ fit_value[i]=val+predicted;
+ fit_value[info->loneighbor[i-2]]&=0x7fff;
+ fit_value[info->hineighbor[i-2]]&=0x7fff;
}else{
fit_value[i]=predicted|0x8000;
@@ -411,34 +317,27 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
return(NULL);
}
-static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
- ogg_int32_t *out){
- vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
- vorbis_info_floor1 *info=look->vi;
+int floor1_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *in,
+ tremor_ogg_int32_t *fit_value,tremor_ogg_int32_t *out){
+ vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
- codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
- int n=ci->blocksizes[vb->W]/2;
+ codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup;
+ int n=ci->blocksizes[vd->W]/2;
int j;
- if(memo){
+ if(fit_value){
/* render the lines */
- int *fit_value=(int *)memo;
int hx=0;
int lx=0;
int ly=fit_value[0]*info->mult;
- /* guard lookup against out-of-range values */
- ly=(ly<0?0:ly>255?255:ly);
-
- for(j=1;j<look->posts;j++){
- int current=look->forward_index[j];
+ for(j=1;j<info->posts;j++){
+ int current=info->forward_index[j];
int hy=fit_value[current]&0x7fff;
if(hy==fit_value[current]){
- hx=info->postlist[current];
hy*=info->mult;
- /* guard lookup against out-of-range values */
- hy=(hy<0?0:hy>255?255:hy);
-
+ hx=info->postlist[current];
+
render_line(n,lx,hx,ly,hy,out);
lx=hx;
@@ -451,10 +350,3 @@ static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
memset(out,0,sizeof(*out)*n);
return(0);
}
-
-/* export hooks */
-vorbis_func_floor floor1_exportbundle={
- &floor1_unpack,&floor1_look,&floor1_free_info,
- &floor1_free_look,&floor1_inverse1,&floor1_inverse2
-};
-
diff --git a/lib/tremor/floor_lookup.c b/lib/tremor/floor_lookup.c
new file mode 100644
index 00000000..a7140a14
--- /dev/null
+++ b/lib/tremor/floor_lookup.c
@@ -0,0 +1,92 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: floor dB lookup
+
+ ********************************************************************/
+
+#include "os.h"
+
+#ifdef _LOW_ACCURACY_
+# define XdB(n) ((((n)>>8)+1)>>1)
+#else
+# define XdB(n) (n)
+#endif
+
+const tremor_ogg_int32_t FLOOR_fromdB_LOOKUP[256]={
+ XdB(0x000000e5), XdB(0x000000f4), XdB(0x00000103), XdB(0x00000114),
+ XdB(0x00000126), XdB(0x00000139), XdB(0x0000014e), XdB(0x00000163),
+ XdB(0x0000017a), XdB(0x00000193), XdB(0x000001ad), XdB(0x000001c9),
+ XdB(0x000001e7), XdB(0x00000206), XdB(0x00000228), XdB(0x0000024c),
+ XdB(0x00000272), XdB(0x0000029b), XdB(0x000002c6), XdB(0x000002f4),
+ XdB(0x00000326), XdB(0x0000035a), XdB(0x00000392), XdB(0x000003cd),
+ XdB(0x0000040c), XdB(0x00000450), XdB(0x00000497), XdB(0x000004e4),
+ XdB(0x00000535), XdB(0x0000058c), XdB(0x000005e8), XdB(0x0000064a),
+ XdB(0x000006b3), XdB(0x00000722), XdB(0x00000799), XdB(0x00000818),
+ XdB(0x0000089e), XdB(0x0000092e), XdB(0x000009c6), XdB(0x00000a69),
+ XdB(0x00000b16), XdB(0x00000bcf), XdB(0x00000c93), XdB(0x00000d64),
+ XdB(0x00000e43), XdB(0x00000f30), XdB(0x0000102d), XdB(0x0000113a),
+ XdB(0x00001258), XdB(0x0000138a), XdB(0x000014cf), XdB(0x00001629),
+ XdB(0x0000179a), XdB(0x00001922), XdB(0x00001ac4), XdB(0x00001c82),
+ XdB(0x00001e5c), XdB(0x00002055), XdB(0x0000226f), XdB(0x000024ac),
+ XdB(0x0000270e), XdB(0x00002997), XdB(0x00002c4b), XdB(0x00002f2c),
+ XdB(0x0000323d), XdB(0x00003581), XdB(0x000038fb), XdB(0x00003caf),
+ XdB(0x000040a0), XdB(0x000044d3), XdB(0x0000494c), XdB(0x00004e10),
+ XdB(0x00005323), XdB(0x0000588a), XdB(0x00005e4b), XdB(0x0000646b),
+ XdB(0x00006af2), XdB(0x000071e5), XdB(0x0000794c), XdB(0x0000812e),
+ XdB(0x00008993), XdB(0x00009283), XdB(0x00009c09), XdB(0x0000a62d),
+ XdB(0x0000b0f9), XdB(0x0000bc79), XdB(0x0000c8b9), XdB(0x0000d5c4),
+ XdB(0x0000e3a9), XdB(0x0000f274), XdB(0x00010235), XdB(0x000112fd),
+ XdB(0x000124dc), XdB(0x000137e4), XdB(0x00014c29), XdB(0x000161bf),
+ XdB(0x000178bc), XdB(0x00019137), XdB(0x0001ab4a), XdB(0x0001c70e),
+ XdB(0x0001e4a1), XdB(0x0002041f), XdB(0x000225aa), XdB(0x00024962),
+ XdB(0x00026f6d), XdB(0x000297f0), XdB(0x0002c316), XdB(0x0002f109),
+ XdB(0x000321f9), XdB(0x00035616), XdB(0x00038d97), XdB(0x0003c8b4),
+ XdB(0x000407a7), XdB(0x00044ab2), XdB(0x00049218), XdB(0x0004de23),
+ XdB(0x00052f1e), XdB(0x0005855c), XdB(0x0005e135), XdB(0x00064306),
+ XdB(0x0006ab33), XdB(0x00071a24), XdB(0x0007904b), XdB(0x00080e20),
+ XdB(0x00089422), XdB(0x000922da), XdB(0x0009bad8), XdB(0x000a5cb6),
+ XdB(0x000b091a), XdB(0x000bc0b1), XdB(0x000c8436), XdB(0x000d5471),
+ XdB(0x000e3233), XdB(0x000f1e5f), XdB(0x001019e4), XdB(0x001125c1),
+ XdB(0x00124306), XdB(0x001372d5), XdB(0x0014b663), XdB(0x00160ef7),
+ XdB(0x00177df0), XdB(0x001904c1), XdB(0x001aa4f9), XdB(0x001c603d),
+ XdB(0x001e384f), XdB(0x00202f0f), XdB(0x0022467a), XdB(0x002480b1),
+ XdB(0x0026dff7), XdB(0x002966b3), XdB(0x002c1776), XdB(0x002ef4fc),
+ XdB(0x0032022d), XdB(0x00354222), XdB(0x0038b828), XdB(0x003c67c2),
+ XdB(0x004054ae), XdB(0x004482e8), XdB(0x0048f6af), XdB(0x004db488),
+ XdB(0x0052c142), XdB(0x005821ff), XdB(0x005ddc33), XdB(0x0063f5b0),
+ XdB(0x006a74a7), XdB(0x00715faf), XdB(0x0078bdce), XdB(0x0080967f),
+ XdB(0x0088f1ba), XdB(0x0091d7f9), XdB(0x009b5247), XdB(0x00a56a41),
+ XdB(0x00b02a27), XdB(0x00bb9ce2), XdB(0x00c7ce12), XdB(0x00d4ca17),
+ XdB(0x00e29e20), XdB(0x00f15835), XdB(0x0101074b), XdB(0x0111bb4e),
+ XdB(0x01238531), XdB(0x01367704), XdB(0x014aa402), XdB(0x016020a7),
+ XdB(0x017702c3), XdB(0x018f6190), XdB(0x01a955cb), XdB(0x01c4f9cf),
+ XdB(0x01e269a8), XdB(0x0201c33b), XdB(0x0223265a), XdB(0x0246b4ea),
+ XdB(0x026c9302), XdB(0x0294e716), XdB(0x02bfda13), XdB(0x02ed9793),
+ XdB(0x031e4e09), XdB(0x03522ee4), XdB(0x03896ed0), XdB(0x03c445e2),
+ XdB(0x0402efd6), XdB(0x0445ac4b), XdB(0x048cbefc), XdB(0x04d87013),
+ XdB(0x05290c67), XdB(0x057ee5ca), XdB(0x05da5364), XdB(0x063bb204),
+ XdB(0x06a36485), XdB(0x0711d42b), XdB(0x0787710e), XdB(0x0804b299),
+ XdB(0x088a17ef), XdB(0x0918287e), XdB(0x09af747c), XdB(0x0a50957e),
+ XdB(0x0afc2f19), XdB(0x0bb2ef7f), XdB(0x0c759034), XdB(0x0d44d6ca),
+ XdB(0x0e2195bc), XdB(0x0f0cad0d), XdB(0x10070b62), XdB(0x1111aeea),
+ XdB(0x122da66c), XdB(0x135c120f), XdB(0x149e24d9), XdB(0x15f525b1),
+ XdB(0x176270e3), XdB(0x18e7794b), XdB(0x1a85c9ae), XdB(0x1c3f06d1),
+ XdB(0x1e14f07d), XdB(0x200963d7), XdB(0x221e5ccd), XdB(0x2455f870),
+ XdB(0x26b2770b), XdB(0x29363e2b), XdB(0x2be3db5c), XdB(0x2ebe06b6),
+ XdB(0x31c7a55b), XdB(0x3503ccd4), XdB(0x3875c5aa), XdB(0x3c210f44),
+ XdB(0x4009632b), XdB(0x4432b8cf), XdB(0x48a149bc), XdB(0x4d59959e),
+ XdB(0x52606733), XdB(0x57bad899), XdB(0x5d6e593a), XdB(0x6380b298),
+ XdB(0x69f80e9a), XdB(0x70dafda8), XdB(0x78307d76), XdB(0x7fffffff),
+};
+
diff --git a/lib/tremor/framing.c b/lib/tremor/framing.c
new file mode 100644
index 00000000..e2321ae4
--- /dev/null
+++ b/lib/tremor/framing.c
@@ -0,0 +1,1117 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: decode Ogg streams back into raw packets
+
+ 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 "tremor_ogg.h"
+#include "misc.h"
+
+
+/* A complete description of Ogg framing exists in docs/framing.html */
+
+/* basic, centralized Ogg memory management based on linked lists of
+ references to refcounted memory buffers. References and buffers
+ are both recycled. Buffers are passed around and consumed in
+ reference form. */
+
+static tremor_ogg_buffer_state *tremor_ogg_buffer_create(void){
+ tremor_ogg_buffer_state *bs=_tremor_ogg_calloc(1,sizeof(*bs));
+ return bs;
+}
+
+/* destruction is 'lazy'; there may be memory references outstanding,
+ and yanking the buffer state out from underneath would be
+ antisocial. Dealloc what is currently unused and have
+ _release_one watch for the stragglers to come in. When they do,
+ finish destruction. */
+
+/* call the helper while holding lock */
+static void _tremor_ogg_buffer_destroy(tremor_ogg_buffer_state *bs){
+ tremor_ogg_buffer *bt;
+ tremor_ogg_reference *rt;
+
+ if(bs->shutdown){
+
+ bt=bs->unused_buffers;
+ rt=bs->unused_references;
+
+ while(bt){
+ tremor_ogg_buffer *b=bt;
+ bt=b->ptr.next;
+ if(b->data)_tremor_ogg_free(b->data);
+ _tremor_ogg_free(b);
+ }
+ bs->unused_buffers=0;
+ while(rt){
+ tremor_ogg_reference *r=rt;
+ rt=r->next;
+ _tremor_ogg_free(r);
+ }
+ bs->unused_references=0;
+
+ if(!bs->outstanding)
+ _tremor_ogg_free(bs);
+
+ }
+}
+
+static void tremor_ogg_buffer_destroy(tremor_ogg_buffer_state *bs){
+ bs->shutdown=1;
+ _tremor_ogg_buffer_destroy(bs);
+}
+
+static tremor_ogg_buffer *_fetch_buffer(tremor_ogg_buffer_state *bs,long bytes){
+ tremor_ogg_buffer *ob;
+ bs->outstanding++;
+
+ /* do we have an unused buffer sitting in the pool? */
+ if(bs->unused_buffers){
+ ob=bs->unused_buffers;
+ bs->unused_buffers=ob->ptr.next;
+
+ /* if the unused buffer is too small, grow it */
+ if(ob->size<bytes){
+ ob->data=_tremor_ogg_realloc(ob->data,bytes);
+ ob->size=bytes;
+ }
+ }else{
+ /* allocate a new buffer */
+ ob=_tremor_ogg_malloc(sizeof(*ob));
+ ob->data=_tremor_ogg_malloc(bytes<16?16:bytes);
+ ob->size=bytes;
+ }
+
+ ob->refcount=1;
+ ob->ptr.owner=bs;
+ return ob;
+}
+
+static tremor_ogg_reference *_fetch_ref(tremor_ogg_buffer_state *bs){
+ tremor_ogg_reference *or;
+ bs->outstanding++;
+
+ /* do we have an unused reference sitting in the pool? */
+ if(bs->unused_references){
+ or=bs->unused_references;
+ bs->unused_references=or->next;
+ }else{
+ /* allocate a new reference */
+ or=_tremor_ogg_malloc(sizeof(*or));
+ }
+
+ or->begin=0;
+ or->length=0;
+ or->next=0;
+ return or;
+}
+
+/* fetch a reference pointing to a fresh, initially continguous buffer
+ of at least [bytes] length */
+static tremor_ogg_reference *tremor_ogg_buffer_alloc(tremor_ogg_buffer_state *bs,long bytes){
+ tremor_ogg_buffer *ob=_fetch_buffer(bs,bytes);
+ tremor_ogg_reference *or=_fetch_ref(bs);
+ or->buffer=ob;
+ return or;
+}
+
+/* enlarge the data buffer in the current link */
+static void tremor_ogg_buffer_realloc(tremor_ogg_reference *or,long bytes){
+ tremor_ogg_buffer *ob=or->buffer;
+
+ /* if the unused buffer is too small, grow it */
+ if(ob->size<bytes){
+ ob->data=_tremor_ogg_realloc(ob->data,bytes);
+ ob->size=bytes;
+ }
+}
+
+static void _tremor_ogg_buffer_mark_one(tremor_ogg_reference *or){
+ or->buffer->refcount++;
+}
+
+/* increase the refcount of the buffers to which the reference points */
+static void tremor_ogg_buffer_mark(tremor_ogg_reference *or){
+ while(or){
+ _tremor_ogg_buffer_mark_one(or);
+ or=or->next;
+ }
+}
+
+/* duplicate a reference (pointing to the same actual buffer memory)
+ and increment buffer refcount. If the desired segment is zero
+ length, a zero length ref is returned. */
+static tremor_ogg_reference *tremor_ogg_buffer_sub(tremor_ogg_reference *or,long length){
+ tremor_ogg_reference *ret=0,*head=0;
+
+ /* duplicate the reference chain; increment refcounts */
+ while(or && length){
+ tremor_ogg_reference *temp=_fetch_ref(or->buffer->ptr.owner);
+ if(head)
+ head->next=temp;
+ else
+ ret=temp;
+ head=temp;
+ head->buffer=or->buffer;
+ head->begin=or->begin;
+ head->length=length;
+ if(head->length>or->length)
+ head->length=or->length;
+
+ length-=head->length;
+ or=or->next;
+ }
+
+ tremor_ogg_buffer_mark(ret);
+ return ret;
+}
+
+tremor_ogg_reference *tremor_ogg_buffer_dup(tremor_ogg_reference *or){
+ tremor_ogg_reference *ret=0,*head=0;
+ /* duplicate the reference chain; increment refcounts */
+ while(or){
+ tremor_ogg_reference *temp=_fetch_ref(or->buffer->ptr.owner);
+ if(head)
+ head->next=temp;
+ else
+ ret=temp;
+ head=temp;
+ head->buffer=or->buffer;
+ head->begin=or->begin;
+ head->length=or->length;
+ or=or->next;
+ }
+
+ tremor_ogg_buffer_mark(ret);
+ return ret;
+}
+
+/* split a reference into two references; 'return' is a reference to
+ the buffer preceeding pos and 'head'/'tail' are the buffer past the
+ split. If pos is at or past the end of the passed in segment,
+ 'head/tail' are NULL */
+static tremor_ogg_reference *tremor_ogg_buffer_split(tremor_ogg_reference **tail,
+ tremor_ogg_reference **head,long pos){
+
+ /* walk past any preceeding fragments to one of:
+ a) the exact boundary that seps two fragments
+ b) the fragment that needs split somewhere in the middle */
+ tremor_ogg_reference *ret=*tail;
+ tremor_ogg_reference *or=*tail;
+
+ while(or && pos>or->length){
+ pos-=or->length;
+ or=or->next;
+ }
+
+ if(!or || pos==0){
+
+ return 0;
+
+ }else{
+
+ if(pos>=or->length){
+ /* exact split, or off the end? */
+ if(or->next){
+
+ /* a split */
+ *tail=or->next;
+ or->next=0;
+
+ }else{
+
+ /* off or at the end */
+ *tail=*head=0;
+
+ }
+ }else{
+
+ /* split within a fragment */
+ long lengthA=pos;
+ long beginB=or->begin+pos;
+ long lengthB=or->length-pos;
+
+ /* make a new reference to tail the second piece */
+ *tail=_fetch_ref(or->buffer->ptr.owner);
+
+ (*tail)->buffer=or->buffer;
+ (*tail)->begin=beginB;
+ (*tail)->length=lengthB;
+ (*tail)->next=or->next;
+ _tremor_ogg_buffer_mark_one(*tail);
+ if(head && or==*head)*head=*tail;
+
+ /* update the first piece */
+ or->next=0;
+ or->length=lengthA;
+
+ }
+ }
+ return ret;
+}
+
+static void tremor_ogg_buffer_release_one(tremor_ogg_reference *or){
+ tremor_ogg_buffer *ob=or->buffer;
+ tremor_ogg_buffer_state *bs=ob->ptr.owner;
+
+ ob->refcount--;
+ if(ob->refcount==0){
+ bs->outstanding--; /* for the returned buffer */
+ ob->ptr.next=bs->unused_buffers;
+ bs->unused_buffers=ob;
+ }
+
+ bs->outstanding--; /* for the returned reference */
+ or->next=bs->unused_references;
+ bs->unused_references=or;
+
+ _tremor_ogg_buffer_destroy(bs); /* lazy cleanup (if needed) */
+
+}
+
+/* release the references, decrease the refcounts of buffers to which
+ they point, release any buffers with a refcount that drops to zero */
+static void tremor_ogg_buffer_release(tremor_ogg_reference *or){
+ while(or){
+ tremor_ogg_reference *next=or->next;
+ tremor_ogg_buffer_release_one(or);
+ or=next;
+ }
+}
+
+static tremor_ogg_reference *tremor_ogg_buffer_pretruncate(tremor_ogg_reference *or,long pos){
+ /* release preceeding fragments we don't want */
+ while(or && pos>=or->length){
+ tremor_ogg_reference *next=or->next;
+ pos-=or->length;
+ tremor_ogg_buffer_release_one(or);
+ or=next;
+ }
+ if (or) {
+ or->begin+=pos;
+ or->length-=pos;
+ }
+ return or;
+}
+
+static tremor_ogg_reference *tremor_ogg_buffer_walk(tremor_ogg_reference *or){
+ if(!or)return NULL;
+ while(or->next){
+ or=or->next;
+ }
+ return(or);
+}
+
+/* *head is appended to the front end (head) of *tail; both continue to
+ be valid pointers, with *tail at the tail and *head at the head */
+static tremor_ogg_reference *tremor_ogg_buffer_cat(tremor_ogg_reference *tail, tremor_ogg_reference *head){
+ if(!tail)return head;
+
+ while(tail->next){
+ tail=tail->next;
+ }
+ tail->next=head;
+ return tremor_ogg_buffer_walk(head);
+}
+
+static void _positionB(oggbyte_buffer *b,int pos){
+ if(pos<b->pos){
+ /* start at beginning, scan forward */
+ b->ref=b->baseref;
+ b->pos=0;
+ b->end=b->pos+b->ref->length;
+ b->ptr=b->ref->buffer->data+b->ref->begin;
+ }
+}
+
+static void _positionF(oggbyte_buffer *b,int pos){
+ /* scan forward for position */
+ while(pos>=b->end){
+ /* just seek forward */
+ b->pos+=b->ref->length;
+ b->ref=b->ref->next;
+ b->end=b->ref->length+b->pos;
+ b->ptr=b->ref->buffer->data+b->ref->begin;
+ }
+}
+
+static int oggbyte_init(oggbyte_buffer *b,tremor_ogg_reference *or){
+ memset(b,0,sizeof(*b));
+ if(or){
+ b->ref=b->baseref=or;
+ b->pos=0;
+ b->end=b->ref->length;
+ b->ptr=b->ref->buffer->data+b->ref->begin;
+ return 0;
+ }else
+ return -1;
+}
+
+static void oggbyte_set4(oggbyte_buffer *b,tremor_ogg_uint32_t val,int pos){
+ int i;
+ _positionB(b,pos);
+ for(i=0;i<4;i++){
+ _positionF(b,pos);
+ b->ptr[pos-b->pos]=val;
+ val>>=8;
+ ++pos;
+ }
+}
+
+static unsigned char oggbyte_read1(oggbyte_buffer *b,int pos){
+ _positionB(b,pos);
+ _positionF(b,pos);
+ return b->ptr[pos-b->pos];
+}
+
+static tremor_ogg_uint32_t oggbyte_read4(oggbyte_buffer *b,int pos){
+ tremor_ogg_uint32_t ret;
+ _positionB(b,pos);
+ _positionF(b,pos);
+ ret=b->ptr[pos-b->pos];
+ _positionF(b,++pos);
+ ret|=b->ptr[pos-b->pos]<<8;
+ _positionF(b,++pos);
+ ret|=b->ptr[pos-b->pos]<<16;
+ _positionF(b,++pos);
+ ret|=b->ptr[pos-b->pos]<<24;
+ return ret;
+}
+
+static tremor_ogg_int64_t oggbyte_read8(oggbyte_buffer *b,int pos){
+ tremor_ogg_int64_t ret;
+ unsigned char t[7];
+ int i;
+ _positionB(b,pos);
+ for(i=0;i<7;i++){
+ _positionF(b,pos);
+ t[i]=b->ptr[pos++ -b->pos];
+ }
+
+ _positionF(b,pos);
+ ret=b->ptr[pos-b->pos];
+
+ for(i=6;i>=0;--i)
+ ret= ret<<8 | t[i];
+
+ return ret;
+}
+
+/* Now we get to the actual framing code */
+
+int tremor_ogg_page_version(tremor_ogg_page *og){
+ oggbyte_buffer ob;
+ if(oggbyte_init(&ob,og->header))return -1;
+ return oggbyte_read1(&ob,4);
+}
+
+int tremor_ogg_page_continued(tremor_ogg_page *og){
+ oggbyte_buffer ob;
+ if(oggbyte_init(&ob,og->header))return -1;
+ return oggbyte_read1(&ob,5)&0x01;
+}
+
+int tremor_ogg_page_bos(tremor_ogg_page *og){
+ oggbyte_buffer ob;
+ if(oggbyte_init(&ob,og->header))return -1;
+ return oggbyte_read1(&ob,5)&0x02;
+}
+
+int tremor_ogg_page_eos(tremor_ogg_page *og){
+ oggbyte_buffer ob;
+ if(oggbyte_init(&ob,og->header))return -1;
+ return oggbyte_read1(&ob,5)&0x04;
+}
+
+tremor_ogg_int64_t tremor_ogg_page_granulepos(tremor_ogg_page *og){
+ oggbyte_buffer ob;
+ if(oggbyte_init(&ob,og->header))return -1;
+ return oggbyte_read8(&ob,6);
+}
+
+tremor_ogg_uint32_t tremor_ogg_page_serialno(tremor_ogg_page *og){
+ oggbyte_buffer ob;
+ if(oggbyte_init(&ob,og->header)) return 0xffffffffUL;
+ return oggbyte_read4(&ob,14);
+}
+
+tremor_ogg_uint32_t tremor_ogg_page_pageno(tremor_ogg_page *og){
+ oggbyte_buffer ob;
+ if(oggbyte_init(&ob,og->header))return 0xffffffffUL;
+ return oggbyte_read4(&ob,18);
+}
+
+/* returns the number of packets that are completed on this page (if
+ the leading packet is begun on a previous page, but ends on this
+ page, it's counted */
+
+/* NOTE:
+If a page consists of a packet begun on a previous page, and a new
+packet begun (but not completed) on this page, the return will be:
+ tremor_ogg_page_packets(page) ==1,
+ tremor_ogg_page_continued(page) !=0
+
+If a page happens to be a single packet that was begun on a
+previous page, and spans to the next page (in the case of a three or
+more page packet), the return will be:
+ tremor_ogg_page_packets(page) ==0,
+ tremor_ogg_page_continued(page) !=0
+*/
+
+int tremor_ogg_page_packets(tremor_ogg_page *og){
+ int i;
+ int n;
+ int count=0;
+ oggbyte_buffer ob;
+ oggbyte_init(&ob,og->header);
+
+ n=oggbyte_read1(&ob,26);
+ for(i=0;i<n;i++)
+ if(oggbyte_read1(&ob,27+i)<255)count++;
+ return(count);
+}
+
+/* Static CRC calculation table. See older code in CVS for dead
+ run-time initialization code. */
+
+static tremor_ogg_uint32_t crc_lookup[256]={
+ 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
+ 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
+ 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
+ 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
+ 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
+ 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
+ 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
+ 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
+ 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
+ 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
+ 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
+ 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
+ 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
+ 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
+ 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
+ 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
+ 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
+ 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
+ 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
+ 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
+ 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
+ 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
+ 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
+ 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
+ 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
+ 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
+ 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
+ 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
+ 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
+ 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
+ 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
+ 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
+ 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
+ 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
+ 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
+ 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
+ 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
+ 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
+ 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
+ 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
+ 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
+ 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
+ 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
+ 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
+ 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
+ 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
+ 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
+ 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
+ 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
+ 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
+ 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
+ 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
+ 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
+ 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
+ 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
+ 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
+ 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
+ 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
+ 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
+ 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
+ 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
+ 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
+ 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
+ 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
+
+tremor_ogg_sync_state *tremor_ogg_sync_create(void){
+ tremor_ogg_sync_state *oy=_tremor_ogg_calloc(1,sizeof(*oy));
+ memset(oy,0,sizeof(*oy));
+ oy->bufferpool=tremor_ogg_buffer_create();
+ return oy;
+}
+
+int tremor_ogg_sync_destroy(tremor_ogg_sync_state *oy){
+ if(oy){
+ tremor_ogg_sync_reset(oy);
+ tremor_ogg_buffer_destroy(oy->bufferpool);
+ memset(oy,0,sizeof(*oy));
+ _tremor_ogg_free(oy);
+ }
+ return OGG_SUCCESS;
+}
+
+unsigned char *tremor_ogg_sync_bufferin(tremor_ogg_sync_state *oy, long bytes){
+
+ /* [allocate and] expose a buffer for data submission.
+
+ If there is no head fragment
+ allocate one and expose it
+ else
+ if the current head fragment has sufficient unused space
+ expose it
+ else
+ if the current head fragment is unused
+ resize and expose it
+ else
+ allocate new fragment and expose it
+ */
+
+ /* base case; fifo uninitialized */
+ if(!oy->fifo_head){
+ oy->fifo_head=oy->fifo_tail=tremor_ogg_buffer_alloc(oy->bufferpool,bytes);
+ return oy->fifo_head->buffer->data;
+ }
+
+ /* space left in current fragment case */
+ if(oy->fifo_head->buffer->size-
+ oy->fifo_head->length-
+ oy->fifo_head->begin >= bytes)
+ return oy->fifo_head->buffer->data+
+ oy->fifo_head->length+oy->fifo_head->begin;
+
+ /* current fragment is unused, but too small */
+ if(!oy->fifo_head->length){
+ tremor_ogg_buffer_realloc(oy->fifo_head,bytes);
+ return oy->fifo_head->buffer->data+oy->fifo_head->begin;
+ }
+
+ /* current fragment used/full; get new fragment */
+ {
+ tremor_ogg_reference *new=tremor_ogg_buffer_alloc(oy->bufferpool,bytes);
+ oy->fifo_head->next=new;
+ oy->fifo_head=new;
+ }
+ return oy->fifo_head->buffer->data;
+}
+
+int tremor_ogg_sync_wrote(tremor_ogg_sync_state *oy, long bytes){
+ if(!oy->fifo_head)return OGG_EINVAL;
+ if(oy->fifo_head->buffer->size-oy->fifo_head->length-oy->fifo_head->begin <
+ bytes)return OGG_EINVAL;
+ oy->fifo_head->length+=bytes;
+ oy->fifo_fill+=bytes;
+ return OGG_SUCCESS;
+}
+
+static tremor_ogg_uint32_t _checksum(tremor_ogg_reference *or, int bytes){
+ tremor_ogg_uint32_t crc_reg=0;
+ int j,post;
+
+ while(or){
+ unsigned char *data=or->buffer->data+or->begin;
+ post=(bytes<or->length?bytes:or->length);
+ for(j=0;j<post;++j)
+ crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^data[j]];
+ bytes-=j;
+ or=or->next;
+ }
+
+ return crc_reg;
+}
+
+
+/* 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 tremor_ogg_sync_pageseek(tremor_ogg_sync_state *oy,tremor_ogg_page *og){
+ oggbyte_buffer page;
+ long bytes,ret=0;
+
+ tremor_ogg_page_release(og);
+
+ bytes=oy->fifo_fill;
+ oggbyte_init(&page,oy->fifo_tail);
+
+ if(oy->headerbytes==0){
+ if(bytes<27)goto sync_out; /* not enough for even a minimal header */
+
+ /* verify capture pattern */
+ if(oggbyte_read1(&page,0)!=(int)'O' ||
+ oggbyte_read1(&page,1)!=(int)'g' ||
+ oggbyte_read1(&page,2)!=(int)'g' ||
+ oggbyte_read1(&page,3)!=(int)'S' ) goto sync_fail;
+
+ oy->headerbytes=oggbyte_read1(&page,26)+27;
+ }
+ if(bytes<oy->headerbytes)goto sync_out; /* not enough for header +
+ seg table */
+ if(oy->bodybytes==0){
+ int i;
+ /* count up body length in the segment table */
+ for(i=0;i<oy->headerbytes-27;i++)
+ oy->bodybytes+=oggbyte_read1(&page,27+i);
+ }
+
+ if(oy->bodybytes+oy->headerbytes>bytes)goto sync_out;
+
+ /* we have what appears to be a complete page; last test: verify
+ checksum */
+ {
+ tremor_ogg_uint32_t chksum=oggbyte_read4(&page,22);
+ oggbyte_set4(&page,0,22);
+
+ /* Compare checksums; memory continues to be common access */
+ if(chksum!=_checksum(oy->fifo_tail,oy->bodybytes+oy->headerbytes)){
+
+ /* D'oh. Mismatch! Corrupt page (or miscapture and not a page
+ at all). replace the computed checksum with the one actually
+ read in; remember all the memory is common access */
+
+ oggbyte_set4(&page,chksum,22);
+ goto sync_fail;
+ }
+ oggbyte_set4(&page,chksum,22);
+ }
+
+ /* We have a page. Set up page return. */
+ if(og){
+ /* set up page output */
+ og->header=tremor_ogg_buffer_split(&oy->fifo_tail,&oy->fifo_head,oy->headerbytes);
+ og->header_len=oy->headerbytes;
+ og->body=tremor_ogg_buffer_split(&oy->fifo_tail,&oy->fifo_head,oy->bodybytes);
+ og->body_len=oy->bodybytes;
+ }else{
+ /* simply advance */
+ oy->fifo_tail=
+ tremor_ogg_buffer_pretruncate(oy->fifo_tail,oy->headerbytes+oy->bodybytes);
+ if(!oy->fifo_tail)oy->fifo_head=0;
+ }
+
+ ret=oy->headerbytes+oy->bodybytes;
+ oy->unsynced=0;
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+ oy->fifo_fill-=ret;
+
+ return ret;
+
+ sync_fail:
+
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+ oy->fifo_tail=tremor_ogg_buffer_pretruncate(oy->fifo_tail,1);
+ ret--;
+
+ /* search forward through fragments for possible capture */
+ while(oy->fifo_tail){
+ /* invariant: fifo_cursor points to a position in fifo_tail */
+ unsigned char *now=oy->fifo_tail->buffer->data+oy->fifo_tail->begin;
+ unsigned char *next=memchr(now, 'O', oy->fifo_tail->length);
+
+ if(next){
+ /* possible capture in this segment */
+ long bytes=next-now;
+ oy->fifo_tail=tremor_ogg_buffer_pretruncate(oy->fifo_tail,bytes);
+ ret-=bytes;
+ break;
+ }else{
+ /* no capture. advance to next segment */
+ long bytes=oy->fifo_tail->length;
+ ret-=bytes;
+ oy->fifo_tail=tremor_ogg_buffer_pretruncate(oy->fifo_tail,bytes);
+ }
+ }
+ if(!oy->fifo_tail)oy->fifo_head=0;
+ oy->fifo_fill+=ret;
+
+ sync_out:
+ return ret;
+}
+
+/* sync the stream and get a page. Keep trying until we find a page.
+ Supress 'sync errors' after reporting the first.
+
+ return values:
+ OGG_HOLE) 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 tremor_ogg_sync_pageout(tremor_ogg_sync_state *oy, tremor_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=tremor_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 OGG_HOLE;
+ }
+
+ /* loop. keep looking */
+
+ }
+}
+
+/* clear things to an initial state. Good to call, eg, before seeking */
+int tremor_ogg_sync_reset(tremor_ogg_sync_state *oy){
+
+ tremor_ogg_buffer_release(oy->fifo_tail);
+ oy->fifo_tail=0;
+ oy->fifo_head=0;
+ oy->fifo_fill=0;
+
+ oy->unsynced=0;
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+ return OGG_SUCCESS;
+}
+
+tremor_ogg_stream_state *tremor_ogg_stream_create(int serialno){
+ tremor_ogg_stream_state *os=_tremor_ogg_calloc(1,sizeof(*os));
+ os->serialno=serialno;
+ os->pageno=-1;
+ return os;
+}
+
+int tremor_ogg_stream_destroy(tremor_ogg_stream_state *os){
+ if(os){
+ tremor_ogg_buffer_release(os->header_tail);
+ tremor_ogg_buffer_release(os->body_tail);
+ memset(os,0,sizeof(*os));
+ _tremor_ogg_free(os);
+ }
+ return OGG_SUCCESS;
+}
+
+
+#define FINFLAG 0x80000000UL
+#define FINMASK 0x7fffffffUL
+
+static void _next_lace(oggbyte_buffer *ob,tremor_ogg_stream_state *os){
+ /* search ahead one lace */
+ os->body_fill_next=0;
+ while(os->laceptr<os->lacing_fill){
+ int val=oggbyte_read1(ob,27+os->laceptr++);
+ os->body_fill_next+=val;
+ if(val<255){
+ os->body_fill_next|=FINFLAG;
+ os->clearflag=1;
+ break;
+ }
+ }
+}
+
+static void _span_queued_page(tremor_ogg_stream_state *os){
+ while( !(os->body_fill&FINFLAG) ){
+
+ if(!os->header_tail)break;
+
+ /* first flush out preceeding page header (if any). Body is
+ flushed as it's consumed, so that's not done here. */
+
+ if(os->lacing_fill>=0)
+ os->header_tail=tremor_ogg_buffer_pretruncate(os->header_tail,
+ os->lacing_fill+27);
+ os->lacing_fill=0;
+ os->laceptr=0;
+ os->clearflag=0;
+
+ if(!os->header_tail){
+ os->header_head=0;
+ break;
+ }else{
+
+ /* process/prepare next page, if any */
+
+ long pageno;
+ oggbyte_buffer ob;
+ tremor_ogg_page og; /* only for parsing header values */
+ og.header=os->header_tail; /* only for parsing header values */
+ pageno=tremor_ogg_page_pageno(&og);
+
+ oggbyte_init(&ob,os->header_tail);
+ os->lacing_fill=oggbyte_read1(&ob,26);
+
+ /* are we in sequence? */
+ if(pageno!=os->pageno){
+ if(os->pageno==-1) /* indicates seek or reset */
+ os->holeflag=1; /* set for internal use */
+ else
+ os->holeflag=2; /* set for external reporting */
+
+ os->body_tail=tremor_ogg_buffer_pretruncate(os->body_tail,
+ os->body_fill);
+ if(os->body_tail==0)os->body_head=0;
+ os->body_fill=0;
+
+ }
+
+ if(tremor_ogg_page_continued(&og)){
+ if(os->body_fill==0){
+ /* continued packet, but no preceeding data to continue */
+ /* dump the first partial packet on the page */
+ _next_lace(&ob,os);
+ os->body_tail=
+ tremor_ogg_buffer_pretruncate(os->body_tail,os->body_fill_next&FINMASK);
+ if(os->body_tail==0)os->body_head=0;
+ /* set span flag */
+ if(!os->spanflag && !os->holeflag)os->spanflag=2;
+ }
+ }else{
+ if(os->body_fill>0){
+ /* preceeding data to continue, but not a continued page */
+ /* dump body_fill */
+ os->body_tail=tremor_ogg_buffer_pretruncate(os->body_tail,
+ os->body_fill);
+ if(os->body_tail==0)os->body_head=0;
+ os->body_fill=0;
+
+ /* set espan flag */
+ if(!os->spanflag && !os->holeflag)os->spanflag=2;
+ }
+ }
+
+ if(os->laceptr<os->lacing_fill){
+ os->granulepos=tremor_ogg_page_granulepos(&og);
+
+ /* get current packet size & flag */
+ _next_lace(&ob,os);
+ os->body_fill+=os->body_fill_next; /* addition handles the flag fine;
+ unsigned on purpose */
+ /* ...and next packet size & flag */
+ _next_lace(&ob,os);
+
+ }
+
+ os->pageno=pageno+1;
+ os->e_o_s=tremor_ogg_page_eos(&og);
+ os->b_o_s=tremor_ogg_page_bos(&og);
+
+ }
+ }
+}
+
+/* add the incoming page to the stream state; we decompose the page
+ into packet segments here as well. */
+
+int tremor_ogg_stream_pagein(tremor_ogg_stream_state *os, tremor_ogg_page *og){
+
+ int serialno=tremor_ogg_page_serialno(og);
+ int version=tremor_ogg_page_version(og);
+
+ /* check the serial number */
+ if(serialno!=os->serialno){
+ tremor_ogg_page_release(og);
+ return OGG_ESERIAL;
+ }
+ if(version>0){
+ tremor_ogg_page_release(og);
+ return OGG_EVERSION;
+ }
+
+ /* add to fifos */
+ if(!os->body_tail){
+ os->body_tail=og->body;
+ os->body_head=tremor_ogg_buffer_walk(og->body);
+ }else{
+ os->body_head=tremor_ogg_buffer_cat(os->body_head,og->body);
+ }
+ if(!os->header_tail){
+ os->header_tail=og->header;
+ os->header_head=tremor_ogg_buffer_walk(og->header);
+ os->lacing_fill=-27;
+ }else{
+ os->header_head=tremor_ogg_buffer_cat(os->header_head,og->header);
+ }
+
+ memset(og,0,sizeof(*og));
+ return OGG_SUCCESS;
+}
+
+int tremor_ogg_stream_reset(tremor_ogg_stream_state *os){
+
+ tremor_ogg_buffer_release(os->header_tail);
+ tremor_ogg_buffer_release(os->body_tail);
+ os->header_tail=os->header_head=0;
+ os->body_tail=os->body_head=0;
+
+ os->e_o_s=0;
+ os->b_o_s=0;
+ os->pageno=-1;
+ os->packetno=0;
+ os->granulepos=0;
+
+ os->body_fill=0;
+ os->lacing_fill=0;
+
+ os->holeflag=0;
+ os->spanflag=0;
+ os->clearflag=0;
+ os->laceptr=0;
+ os->body_fill_next=0;
+
+ return OGG_SUCCESS;
+}
+
+int tremor_ogg_stream_reset_serialno(tremor_ogg_stream_state *os,int serialno){
+ tremor_ogg_stream_reset(os);
+ os->serialno=serialno;
+ return OGG_SUCCESS;
+}
+
+static int _packetout(tremor_ogg_stream_state *os,tremor_ogg_packet *op,int adv){
+
+ tremor_ogg_packet_release(op);
+ _span_queued_page(os);
+
+ if(os->holeflag){
+ int temp=os->holeflag;
+ if(os->clearflag)
+ os->holeflag=0;
+ else
+ os->holeflag=1;
+ if(temp==2){
+ os->packetno++;
+ return OGG_HOLE;
+ }
+ }
+ if(os->spanflag){
+ int temp=os->spanflag;
+ if(os->clearflag)
+ os->spanflag=0;
+ else
+ os->spanflag=1;
+ if(temp==2){
+ os->packetno++;
+ return OGG_SPAN;
+ }
+ }
+
+ if(!(os->body_fill&FINFLAG)) return 0;
+ if(!op && !adv)return 1; /* just using peek as an inexpensive way
+ to ask if there's a whole packet
+ waiting */
+ if(op){
+ op->b_o_s=os->b_o_s;
+ if(os->e_o_s && os->body_fill_next==0)
+ op->e_o_s=os->e_o_s;
+ else
+ op->e_o_s=0;
+ if( (os->body_fill&FINFLAG) && !(os->body_fill_next&FINFLAG) )
+ op->granulepos=os->granulepos;
+ else
+ op->granulepos=-1;
+ op->packetno=os->packetno;
+ }
+
+ if(adv){
+ oggbyte_buffer ob;
+ oggbyte_init(&ob,os->header_tail);
+
+ /* split the body contents off */
+ if(op){
+ op->packet=tremor_ogg_buffer_split(&os->body_tail,&os->body_head,
+ os->body_fill&FINMASK);
+ op->bytes=os->body_fill&FINMASK;
+ }else{
+ os->body_tail=tremor_ogg_buffer_pretruncate(os->body_tail,
+ os->body_fill&FINMASK);
+ if(os->body_tail==0)os->body_head=0;
+ }
+
+ /* update lacing pointers */
+ os->body_fill=os->body_fill_next;
+ _next_lace(&ob,os);
+ }else{
+ if(op){
+ op->packet=tremor_ogg_buffer_sub(os->body_tail,os->body_fill&FINMASK);
+ op->bytes=os->body_fill&FINMASK;
+ }
+ }
+
+ if(adv){
+ os->packetno++;
+ os->b_o_s=0;
+ }
+
+ return 1;
+}
+
+int tremor_ogg_stream_packetout(tremor_ogg_stream_state *os,tremor_ogg_packet *op){
+ return _packetout(os,op,1);
+}
+
+int tremor_ogg_stream_packetpeek(tremor_ogg_stream_state *os,tremor_ogg_packet *op){
+ return _packetout(os,op,0);
+}
+
+int tremor_ogg_packet_release(tremor_ogg_packet *op) {
+ if(op){
+ tremor_ogg_buffer_release(op->packet);
+ memset(op, 0, sizeof(*op));
+ }
+ return OGG_SUCCESS;
+}
+
+int tremor_ogg_page_release(tremor_ogg_page *og) {
+ if(og){
+ tremor_ogg_buffer_release(og->header);
+ tremor_ogg_buffer_release(og->body);
+ memset(og, 0, sizeof(*og));
+ }
+ return OGG_SUCCESS;
+}
+
+void tremor_ogg_page_dup(tremor_ogg_page *dup,tremor_ogg_page *orig){
+ dup->header_len=orig->header_len;
+ dup->body_len=orig->body_len;
+ dup->header=tremor_ogg_buffer_dup(orig->header);
+ dup->body=tremor_ogg_buffer_dup(orig->body);
+}
+
diff --git a/lib/tremor/info.c b/lib/tremor/info.c
index 24e24ac7..da393f9f 100644
--- a/lib/tremor/info.c
+++ b/lib/tremor/info.c
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -21,19 +21,17 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <limits.h>
-#include <ogg/ogg.h>
+#include "tremor_ogg.h"
#include "ivorbiscodec.h"
#include "codec_internal.h"
#include "codebook.h"
-#include "registry.h"
-#include "window.h"
#include "misc.h"
+#include "os.h"
/* helpers */
-static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
+static void _v_readstring(tremor_oggpack_buffer *o,char *buf,int bytes){
while(bytes--){
- *buf++=oggpack_read(o,8);
+ *buf++=tremor_oggpack_read(o,8);
}
}
@@ -92,15 +90,13 @@ int vorbis_comment_query_count(vorbis_comment *vc, char *tag){
void vorbis_comment_clear(vorbis_comment *vc){
if(vc){
long i;
- if(vc->user_comments){
- for(i=0;i<vc->comments;i++)
- if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
- _ogg_free(vc->user_comments);
- }
- if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
- if(vc->vendor)_ogg_free(vc->vendor);
- memset(vc,0,sizeof(*vc));
+ for(i=0;i<vc->comments;i++)
+ if(vc->user_comments[i])_tremor_ogg_free(vc->user_comments[i]);
+ if(vc->user_comments)_tremor_ogg_free(vc->user_comments);
+ if(vc->comment_lengths)_tremor_ogg_free(vc->comment_lengths);
+ if(vc->vendor)_tremor_ogg_free(vc->vendor);
}
+ memset(vc,0,sizeof(*vc));
}
/* blocksize 0 is guaranteed to be short, 1 is guarantted to be long.
@@ -113,7 +109,7 @@ int vorbis_info_blocksize(vorbis_info *vi,int zo){
/* used by synthesis, which has a full, alloced vi */
void vorbis_info_init(vorbis_info *vi){
memset(vi,0,sizeof(*vi));
- vi->codec_setup=(codec_setup_info *)_ogg_calloc(1,sizeof(codec_setup_info));
+ vi->codec_setup=(codec_setup_info *)_tremor_ogg_calloc(1,sizeof(codec_setup_info));
}
void vorbis_info_clear(vorbis_info *vi){
@@ -122,33 +118,37 @@ void vorbis_info_clear(vorbis_info *vi){
if(ci){
- for(i=0;i<ci->modes;i++)
- if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
+ if(ci->mode_param)_tremor_ogg_free(ci->mode_param);
- for(i=0;i<ci->maps;i++) /* unpack does the range checking */
- if(ci->map_param[i])
- _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
+ if(ci->map_param){
+ for(i=0;i<ci->maps;i++) /* unpack does the range checking */
+ mapping_clear_info(ci->map_param+i);
+ _tremor_ogg_free(ci->map_param);
+ }
- for(i=0;i<ci->floors;i++) /* unpack does the range checking */
- if(ci->floor_param[i])
- _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
-
- for(i=0;i<ci->residues;i++) /* unpack does the range checking */
- if(ci->residue_param[i])
- _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
-
- for(i=0;i<ci->books;i++){
- if(ci->book_param[i]){
- /* knows if the book was not alloced */
- vorbis_staticbook_destroy(ci->book_param[i]);
- }
- if(ci->fullbooks)
- vorbis_book_clear(ci->fullbooks+i);
+ if(ci->floor_param){
+ for(i=0;i<ci->floors;i++) /* unpack does the range checking */
+ if(ci->floor_type[i])
+ floor1_free_info(ci->floor_param[i]);
+ else
+ floor0_free_info(ci->floor_param[i]);
+ _tremor_ogg_free(ci->floor_param);
+ _tremor_ogg_free(ci->floor_type);
+ }
+
+ if(ci->residue_param){
+ for(i=0;i<ci->residues;i++) /* unpack does the range checking */
+ res_clear_info(ci->residue_param+i);
+ _tremor_ogg_free(ci->residue_param);
+ }
+
+ if(ci->book_param){
+ for(i=0;i<ci->books;i++)
+ vorbis_book_clear(ci->book_param+i);
+ _tremor_ogg_free(ci->book_param);
}
- if(ci->fullbooks)
- _ogg_free(ci->fullbooks);
- _ogg_free(ci);
+ _tremor_ogg_free(ci);
}
memset(vi,0,sizeof(*vi));
@@ -156,30 +156,36 @@ void vorbis_info_clear(vorbis_info *vi){
/* Header packing/unpacking ********************************************/
-static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
+static int _vorbis_unpack_info(vorbis_info *vi,tremor_oggpack_buffer *opb){
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
if(!ci)return(OV_EFAULT);
- vi->version=oggpack_read(opb,32);
+ vi->version=tremor_oggpack_read(opb,32);
if(vi->version!=0)return(OV_EVERSION);
- vi->channels=oggpack_read(opb,8);
- vi->rate=oggpack_read(opb,32);
+ vi->channels=tremor_oggpack_read(opb,8);
+ vi->rate=tremor_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->bitrate_upper=tremor_oggpack_read(opb,32);
+ vi->bitrate_nominal=tremor_oggpack_read(opb,32);
+ vi->bitrate_lower=tremor_oggpack_read(opb,32);
- ci->blocksizes[0]=1<<oggpack_read(opb,4);
- ci->blocksizes[1]=1<<oggpack_read(opb,4);
+ ci->blocksizes[0]=1<<tremor_oggpack_read(opb,4);
+ ci->blocksizes[1]=1<<tremor_oggpack_read(opb,4);
+#ifdef LIMIT_TO_64kHz
+ if(vi->rate>=64000 || ci->blocksizes[1]>4096)goto err_out;
+#else
+ if(vi->rate<64000 && ci->blocksizes[1]>4096)goto err_out;
+#endif
+
if(vi->rate<1)goto err_out;
if(vi->channels<1)goto err_out;
if(ci->blocksizes[0]<64)goto err_out;
if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
if(ci->blocksizes[1]>8192)goto err_out;
- if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+ if(tremor_oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
return(0);
err_out:
@@ -187,34 +193,25 @@ static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
return(OV_EBADHEADER);
}
-static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
+static int _vorbis_unpack_comment(vorbis_comment *vc,tremor_oggpack_buffer *opb){
int i;
- int vendorlen;
- vendorlen=oggpack_read(opb,32);
+ int vendorlen=tremor_oggpack_read(opb,32);
if(vendorlen<0)goto err_out;
- if(vendorlen>opb->storage-oggpack_bytes(opb))goto err_out;
- vc->vendor=(char *)_ogg_calloc(vendorlen+1,1);
- if(vc->vendor==NULL)goto err_out;
+ vc->vendor=(char *)_tremor_ogg_calloc(vendorlen+1,1);
_v_readstring(opb,vc->vendor,vendorlen);
- i=oggpack_read(opb,32);
- if(i<0||i>=INT_MAX||i>(opb->storage-oggpack_bytes(opb))>>2)goto err_out;
- vc->user_comments=(char **)_ogg_calloc(i+1,sizeof(*vc->user_comments));
- vc->comment_lengths=(int *)_ogg_calloc(i+1, sizeof(*vc->comment_lengths));
- if(vc->user_comments==NULL||vc->comment_lengths==NULL)goto err_out;
- vc->comments=i;
-
+ vc->comments=tremor_oggpack_read(opb,32);
+ if(vc->comments<0)goto err_out;
+ vc->user_comments=(char **)_tremor_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
+ vc->comment_lengths=(int *)_tremor_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
+
for(i=0;i<vc->comments;i++){
- int len=oggpack_read(opb,32);
- if(len<0||len>opb->storage-oggpack_bytes(opb))goto err_out;
- vc->comment_lengths[i]=len;
- vc->user_comments[i]=(char *)_ogg_calloc(len+1,1);
- if(vc->user_comments[i]==NULL){
- vc->comments=i;
- goto err_out;
- }
+ int len=tremor_oggpack_read(opb,32);
+ if(len<0)goto err_out;
+ vc->comment_lengths[i]=len;
+ vc->user_comments[i]=(char *)_tremor_ogg_calloc(len+1,1);
_v_readstring(opb,vc->user_comments[i],len);
- }
- if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+ }
+ if(tremor_oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
return(0);
err_out:
@@ -224,76 +221,63 @@ static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
/* all of the real encoding details are here. The modes, books,
everything */
-static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
+static int _vorbis_unpack_books(vorbis_info *vi,tremor_oggpack_buffer *opb){
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
int i;
+ if(!ci)return(OV_EFAULT);
/* codebooks */
- ci->books=oggpack_read(opb,8)+1;
- if(ci->books<=0)goto err_out;
- for(i=0;i<ci->books;i++){
- ci->book_param[i]=vorbis_staticbook_unpack(opb);
- if(!ci->book_param[i])goto err_out;
- }
+ ci->books=tremor_oggpack_read(opb,8)+1;
+ ci->book_param=(codebook *)_tremor_ogg_calloc(ci->books,sizeof(*ci->book_param));
+ for(i=0;i<ci->books;i++)
+ if(vorbis_book_unpack(opb,ci->book_param+i))goto err_out;
- /* time backend settings */
- ci->times=oggpack_read(opb,6)+1;
- if(ci->times<=0)goto err_out;
- for(i=0;i<ci->times;i++){
- ci->time_type[i]=oggpack_read(opb,16);
- if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out;
- /* ci->time_param[i]=_time_P[ci->time_type[i]]->unpack(vi,opb);
- Vorbis I has no time backend */
- /*if(!ci->time_param[i])goto err_out;*/
- }
+ /* time backend settings, not actually used */
+ i=tremor_oggpack_read(opb,6);
+ for(;i>=0;i--)
+ if(tremor_oggpack_read(opb,16)!=0)goto err_out;
/* floor backend settings */
- ci->floors=oggpack_read(opb,6)+1;
- if(ci->floors<=0)goto err_out;
+ ci->floors=tremor_oggpack_read(opb,6)+1;
+ ci->floor_param=_tremor_ogg_malloc(sizeof(*ci->floor_param)*ci->floors);
+ ci->floor_type=_tremor_ogg_malloc(sizeof(*ci->floor_type)*ci->floors);
for(i=0;i<ci->floors;i++){
- ci->floor_type[i]=oggpack_read(opb,16);
+ ci->floor_type[i]=tremor_oggpack_read(opb,16);
if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
- ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
+ if(ci->floor_type[i])
+ ci->floor_param[i]=floor1_info_unpack(vi,opb);
+ else
+ ci->floor_param[i]=floor0_info_unpack(vi,opb);
if(!ci->floor_param[i])goto err_out;
}
/* residue backend settings */
- ci->residues=oggpack_read(opb,6)+1;
- if(ci->residues<=0)goto err_out;
- for(i=0;i<ci->residues;i++){
- ci->residue_type[i]=oggpack_read(opb,16);
- if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
- ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
- if(!ci->residue_param[i])goto err_out;
- }
+ ci->residues=tremor_oggpack_read(opb,6)+1;
+ ci->residue_param=_tremor_ogg_malloc(sizeof(*ci->residue_param)*ci->residues);
+ for(i=0;i<ci->residues;i++)
+ if(res_unpack(ci->residue_param+i,vi,opb))goto err_out;
/* map backend settings */
- ci->maps=oggpack_read(opb,6)+1;
- if(ci->maps<=0)goto err_out;
+ ci->maps=tremor_oggpack_read(opb,6)+1;
+ ci->map_param=_tremor_ogg_malloc(sizeof(*ci->map_param)*ci->maps);
for(i=0;i<ci->maps;i++){
- ci->map_type[i]=oggpack_read(opb,16);
- if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
- ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
- if(!ci->map_param[i])goto err_out;
+ if(tremor_oggpack_read(opb,16)!=0)goto err_out;
+ if(mapping_info_unpack(ci->map_param+i,vi,opb))goto err_out;
}
/* mode settings */
- ci->modes=oggpack_read(opb,6)+1;
- if(ci->modes<=0)goto err_out;
+ ci->modes=tremor_oggpack_read(opb,6)+1;
+ ci->mode_param=
+ (vorbis_info_mode *)_tremor_ogg_malloc(ci->modes*sizeof(*ci->mode_param));
for(i=0;i<ci->modes;i++){
- ci->mode_param[i]=(vorbis_info_mode *)_ogg_calloc(1,sizeof(*ci->mode_param[i]));
- ci->mode_param[i]->blockflag=oggpack_read(opb,1);
- ci->mode_param[i]->windowtype=oggpack_read(opb,16);
- ci->mode_param[i]->transformtype=oggpack_read(opb,16);
- ci->mode_param[i]->mapping=oggpack_read(opb,8);
-
- if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
- if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
- if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
- if(ci->mode_param[i]->mapping<0)goto err_out;
+ ci->mode_param[i].blockflag=tremor_oggpack_read(opb,1);
+ if(tremor_oggpack_read(opb,16))goto err_out;
+ if(tremor_oggpack_read(opb,16))goto err_out;
+ ci->mode_param[i].mapping=tremor_oggpack_read(opb,8);
+ if(ci->mode_param[i].mapping>=ci->maps)goto err_out;
}
- if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
+ if(tremor_oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
return(0);
err_out:
@@ -301,47 +285,22 @@ static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
return(OV_EBADHEADER);
}
-/* Is this packet a vorbis ID header? */
-int vorbis_synthesis_idheader(ogg_packet *op){
- oggpack_buffer opb;
- char buffer[6];
-
- if(op){
- oggpack_readinit(&opb,op->packet,op->bytes);
-
- if(!op->b_o_s)
- return(0); /* Not the initial packet */
-
- if(oggpack_read(&opb,8) != 1)
- return 0; /* not an ID header */
-
- memset(buffer,0,6);
- _v_readstring(&opb,buffer,6);
- if(memcmp(buffer,"vorbis",6))
- return 0; /* not vorbis */
-
- return 1;
- }
-
- return 0;
-}
-
/* 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;
+int vorbis_dsp_headerin(vorbis_info *vi,vorbis_comment *vc,tremor_ogg_packet *op){
+ tremor_oggpack_buffer opb;
if(op){
- oggpack_readinit(&opb,op->packet,op->bytes);
+ tremor_oggpack_readinit(&opb,op->packet);
/* Which of the three types of header is this? */
/* Also verify header-ness, vorbis */
{
char buffer[6];
- int packtype=oggpack_read(&opb,8);
+ int packtype=tremor_oggpack_read(&opb,8);
memset(buffer,0,6);
_v_readstring(&opb,buffer,6);
if(memcmp(buffer,"vorbis",6)){
@@ -366,10 +325,6 @@ int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op)
/* um... we didn't get the initial header */
return(OV_EBADHEADER);
}
- if(vc->vendor!=NULL){
- /* previously initialized comment header */
- return(OV_EBADHEADER);
- }
return(_vorbis_unpack_comment(vc,&opb));
@@ -378,14 +333,6 @@ int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op)
/* um... we didn;t get the initial header or comments yet */
return(OV_EBADHEADER);
}
- if(vi->codec_setup==NULL){
- /* improperly initialized vorbis_info */
- return(OV_EFAULT);
- }
- if(((codec_setup_info *)vi->codec_setup)->books>0){
- /* previously initialized setup header */
- return(OV_EBADHEADER);
- }
return(_vorbis_unpack_books(vi,&opb));
diff --git a/lib/tremor/iseeking_example.c b/lib/tremor/iseeking_example.c
deleted file mode 100644
index dc971ba4..00000000
--- a/lib/tremor/iseeking_example.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
- * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: illustrate seeking, and test it too
- last mod: $Id$
-
- ********************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "ivorbiscodec.h"
-#include "ivorbisfile.h"
-
-#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
-# include <io.h>
-# include <fcntl.h>
-#endif
-
-void _verify(OggVorbis_File *ov,
- ogg_int64_t val,
- ogg_int64_t pcmval,
- ogg_int64_t timeval,
- ogg_int64_t pcmlength,
- char *bigassbuffer){
- int j;
- long bread;
- char buffer[4096];
- int dummy;
- ogg_int64_t pos;
-
- /* verify the raw position, the pcm position and position decode */
- if(val!=-1 && ov_raw_tell(ov)<val){
- fprintf(stderr,"raw position out of tolerance: requested %ld, got %ld\n",
- (long)val,(long)ov_raw_tell(ov));
- exit(1);
- }
- if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
- fprintf(stderr,"pcm position out of tolerance: requested %ld, got %ld\n",
- (long)pcmval,(long)ov_pcm_tell(ov));
- exit(1);
- }
- if(timeval!=-1 && ov_time_tell(ov)>timeval){
- fprintf(stderr,"time position out of tolerance: requested %ld, got %ld\n",
- (long)timeval,(long)ov_time_tell(ov));
- exit(1);
- }
- pos=ov_pcm_tell(ov);
- if(pos<0 || pos>pcmlength){
- fprintf(stderr,"pcm position out of bounds: got %ld\n",(long)pos);
- exit(1);
- }
- bread=ov_read(ov,buffer,4096,&dummy);
- if(bigassbuffer){
- for(j=0;j<bread;j++){
- if(buffer[j]!=bigassbuffer[j+pos*4]){
- fprintf(stderr,"data position after seek doesn't match pcm position\n");
-
- {
- FILE *f=fopen("a.m","w");
- for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)buffer[j]);
- fclose(f);
- f=fopen("b.m","w");
- for(j=0;j<bread;j++)fprintf(f,"%d\n",(int)bigassbuffer[j+pos*2]);
- fclose(f);
- }
-
- exit(1);
- }
- }
- }
-}
-
-int main(){
- OggVorbis_File ov;
- int i,ret;
- ogg_int64_t pcmlength;
- ogg_int64_t timelength;
- char *bigassbuffer;
- int dummy;
-
-#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
- _setmode( _fileno( stdin ), _O_BINARY );
-#endif
-
-
- /* open the file/pipe on stdin */
- if(ov_open(stdin, &ov, NULL, 0) < 0) {
- fprintf(stderr,"Could not open input as an OggVorbis file.\n\n");
- exit(1);
- }
-
- if(ov_seekable(&ov)){
-
- /* to simplify our own lives, we want to assume the whole file is
- stereo. Verify this to avoid potentially mystifying users
- (pissing them off is OK, just don't confuse them) */
- for(i=0;i<ov.links;i++){
- vorbis_info *vi=ov_info(&ov,i);
- if(vi->channels!=2){
- fprintf(stderr,"Sorry; right now seeking_test can only use Vorbis files\n"
- "that are entirely stereo.\n\n");
- exit(1);
- }
- }
-
- /* because we want to do sample-level verification that the seek
- does what it claimed, decode the entire file into memory */
- pcmlength=ov_pcm_total(&ov,-1);
- timelength=ov_time_total(&ov,-1);
- bigassbuffer=malloc(pcmlength*4); /* w00t */
- if(bigassbuffer){
- i=0;
- while(i<pcmlength*4){
- int ret=ov_read(&ov,bigassbuffer+i,pcmlength*4-i,&dummy);
- if(ret<0)continue;
- if(ret){
- i+=ret;
- }else{
- pcmlength=i/4;
- }
- fprintf(stderr,"\rloading.... [%ld left] ",
- (long)(pcmlength*4-i));
- }
- }else{
- fprintf(stderr,"\rfile too large to load into memory for read tests;\n\tonly verifying seek positioning...\n");
- }
-
- {
- ogg_int64_t length=ov.end;
- fprintf(stderr,"\rtesting raw seeking to random places in %ld bytes....\n",
- (long)length);
-
- for(i=0;i<1000;i++){
- ogg_int64_t val=rand()*length/RAND_MAX;
- fprintf(stderr,"\r\t%d [raw position %ld]... ",i,(long)val);
- ret=ov_raw_seek(&ov,val);
- if(ret<0){
- fprintf(stderr,"seek failed: %d\n",ret);
- exit(1);
- }
-
- _verify(&ov,val,-1,-1.,pcmlength,bigassbuffer);
-
- }
- }
-
- fprintf(stderr,"\r");
- {
- fprintf(stderr,"testing pcm page seeking to random places in %ld samples....\n",
- (long)pcmlength);
-
- for(i=0;i<1000;i++){
- ogg_int64_t val=i==0?0:(double)rand()*pcmlength/RAND_MAX;
- fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val);
- ret=ov_pcm_seek_page(&ov,val);
- if(ret<0){
- fprintf(stderr,"seek failed: %d\n",ret);
- exit(1);
- }
-
- _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
-
- }
- }
-
- fprintf(stderr,"\r");
- {
- fprintf(stderr,"testing pcm exact seeking to random places in %ld samples....\n",
- (long)pcmlength);
-
- for(i=0;i<1000;i++){
- ogg_int64_t val=i==0?0:(double)rand()*pcmlength/RAND_MAX;
- fprintf(stderr,"\r\t%d [pcm position %ld]... ",i,(long)val);
- ret=ov_pcm_seek(&ov,val);
- if(ret<0){
- fprintf(stderr,"seek failed: %d\n",ret);
- exit(1);
- }
- if(ov_pcm_tell(&ov)!=val){
- fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
- (long)val,(long)ov_pcm_tell(&ov));
- exit(1);
- }
-
- _verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
-
- }
- }
-
- fprintf(stderr,"\r");
- {
- fprintf(stderr,"testing time page seeking to random places in %ld milliseconds....\n",
- (long)timelength);
-
- for(i=0;i<1000;i++){
- ogg_int64_t val=(double)rand()*timelength/RAND_MAX;
- fprintf(stderr,"\r\t%d [time position %ld]... ",i,(long)val);
- ret=ov_time_seek_page(&ov,val);
- if(ret<0){
- fprintf(stderr,"seek failed: %d\n",ret);
- exit(1);
- }
-
- _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
-
- }
- }
-
- fprintf(stderr,"\r");
- {
- fprintf(stderr,"testing time exact seeking to random places in %ld milliseconds....\n",
- (long)timelength);
-
- for(i=0;i<1000;i++){
- ogg_int64_t val=(double)rand()*timelength/RAND_MAX;
- fprintf(stderr,"\r\t%d [time position %ld]... ",i,(long)val);
- ret=ov_time_seek(&ov,val);
- if(ret<0){
- fprintf(stderr,"seek failed: %d\n",ret);
- exit(1);
- }
- if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){
- fprintf(stderr,"Declared position didn't perfectly match request: %ld != %ld\n",
- (long)val,(long)ov_time_tell(&ov));
- exit(1);
- }
-
- _verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
-
- }
- }
-
- fprintf(stderr,"\r \nOK.\n\n");
-
-
- }else{
- fprintf(stderr,"Standard input was not seekable.\n");
- }
-
- ov_clear(&ov);
- return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/tremor/ivorbiscodec.h b/lib/tremor/ivorbiscodec.h
index 17eab58d..41d4d5da 100644
--- a/lib/tremor/ivorbiscodec.h
+++ b/lib/tremor/ivorbiscodec.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -23,7 +23,10 @@ extern "C"
{
#endif /* __cplusplus */
-#include <ogg/ogg.h>
+#include "tremor_ogg.h"
+
+struct vorbis_dsp_state;
+typedef struct vorbis_dsp_state vorbis_dsp_state;
typedef struct vorbis_info{
int version;
@@ -53,80 +56,7 @@ typedef struct vorbis_info{
void *codec_setup;
} vorbis_info;
-/* vorbis_dsp_state buffers the current vorbis audio
- analysis/synthesis state. The DSP state belongs to a specific
- logical bitstream ****************************************************/
-typedef struct vorbis_dsp_state{
- int analysisp;
- vorbis_info *vi;
-
- ogg_int32_t **pcm;
- ogg_int32_t **pcmret;
- int pcm_storage;
- int pcm_current;
- int pcm_returned;
-
- int preextrapolate;
- int eofflag;
-
- long lW;
- long W;
- long nW;
- long centerW;
-
- ogg_int64_t granulepos;
- ogg_int64_t sequence;
-
- void *backend_state;
-} vorbis_dsp_state;
-
-typedef struct vorbis_block{
- /* necessary stream state for linking to the framing abstraction */
- ogg_int32_t **pcm; /* this is a pointer into local storage */
- oggpack_buffer opb;
-
- long lW;
- long W;
- long nW;
- int pcmend;
- int mode;
-
- int eofflag;
- ogg_int64_t granulepos;
- ogg_int64_t sequence;
- vorbis_dsp_state *vd; /* For read-only access of configuration */
-
- /* local storage to avoid remallocing; it's up to the mapping to
- structure it */
- void *localstore;
- long localtop;
- long localalloc;
- long totaluse;
- struct alloc_chain *reap;
-
-} vorbis_block;
-
-/* vorbis_block is a single block of data to be processed as part of
-the analysis/synthesis stream; it belongs to a specific logical
-bitstream, but is independant from other vorbis_blocks belonging to
-that logical bitstream. *************************************************/
-
-struct alloc_chain{
- void *ptr;
- struct alloc_chain *next;
-};
-
-/* vorbis_info contains all the setup information specific to the
- specific compression/decompression mode in progress (eg,
- psychoacoustic settings, channel setup, options, codebook
- etc). vorbis_info and substructures are in backends.h.
-*********************************************************************/
-
-/* the comments are not part of vorbis_info so that vorbis_info can be
- static storage */
typedef struct vorbis_comment{
- /* unlimited user comment fields. libvorbis writes 'libvorbis'
- whatever vendor is set to in encode */
char **user_comments;
int *comment_lengths;
int comments;
@@ -135,18 +65,6 @@ typedef struct vorbis_comment{
} vorbis_comment;
-/* libvorbis encodes in two abstraction layers; first we perform DSP
- and produce a packet (see docs/analysis.txt). The packet is then
- coded into a framed OggSquish bitstream by the second layer (see
- docs/framing.txt). Decode is the reverse process; we sync/frame
- the bitstream and extract individual packets, then decode the
- packet back into PCM audio.
-
- The extra framing/packetizing is used in streaming formats, such as
- files. Over the net (such as with UDP), the framing and
- packetization aren't necessary as they're provided by the transport
- and the streaming layer is not used */
-
/* Vorbis PRIMITIVES: general ***************************************/
extern void vorbis_info_init(vorbis_info *vi);
@@ -160,24 +78,6 @@ extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count);
extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag);
extern void vorbis_comment_clear(vorbis_comment *vc);
-extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
-extern int vorbis_block_clear(vorbis_block *vb);
-extern void vorbis_dsp_clear(vorbis_dsp_state *v);
-
-/* Vorbis PRIMITIVES: synthesis layer *******************************/
-extern int vorbis_synthesis_idheader(ogg_packet *op);
-extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,
- ogg_packet *op);
-
-extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi);
-extern int vorbis_synthesis_restart(vorbis_dsp_state *v);
-extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op);
-extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op);
-extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb);
-extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm);
-extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples);
-extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
-
/* Vorbis ERRORS and return codes ***********************************/
#define OV_FALSE -1
diff --git a/lib/tremor/ivorbisfile.h b/lib/tremor/ivorbisfile.h
index f6ecb0e4..c8734031 100644
--- a/lib/tremor/ivorbisfile.h
+++ b/lib/tremor/ivorbisfile.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -26,8 +26,6 @@ extern "C"
#include <stdio.h>
#include "ivorbiscodec.h"
-#define CHUNKSIZE 65535
-#define READSIZE 1024
/* The function prototypes for the callbacks are basically the same as for
* the stdio functions fread, fseek, fclose, ftell.
* The one difference is that the FILE * arguments have been replaced with
@@ -40,86 +38,79 @@ extern "C"
*/
typedef struct {
size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource);
- int (*seek_func) (void *datasource, ogg_int64_t offset, int whence);
+ int (*seek_func) (void *datasource, tremor_ogg_int64_t offset, int whence);
int (*close_func) (void *datasource);
long (*tell_func) (void *datasource);
} ov_callbacks;
-#define NOTOPEN 0
-#define PARTOPEN 1
-#define OPENED 2
-#define STREAMSET 3
-#define INITSET 4
-
-typedef struct OggVorbis_File {
+typedef struct TremorOggVorbis_File {
void *datasource; /* Pointer to a FILE *, etc. */
int seekable;
- ogg_int64_t offset;
- ogg_int64_t end;
- ogg_sync_state oy;
+ tremor_ogg_int64_t offset;
+ tremor_ogg_int64_t end;
+ tremor_ogg_sync_state *oy;
/* If the FILE handle isn't seekable (eg, a pipe), only the current
stream appears */
int links;
- ogg_int64_t *offsets;
- ogg_int64_t *dataoffsets;
- ogg_uint32_t *serialnos;
- ogg_int64_t *pcmlengths;
- vorbis_info *vi;
- vorbis_comment *vc;
+ tremor_ogg_int64_t *offsets;
+ tremor_ogg_int64_t *dataoffsets;
+ tremor_ogg_uint32_t *serialnos;
+ tremor_ogg_int64_t *pcmlengths;
+ vorbis_info vi;
+ vorbis_comment vc;
/* Decoding working state local storage */
- ogg_int64_t pcm_offset;
+ tremor_ogg_int64_t pcm_offset;
int ready_state;
- ogg_uint32_t current_serialno;
+ tremor_ogg_uint32_t current_serialno;
int current_link;
- ogg_int64_t bittrack;
- ogg_int64_t samptrack;
+ tremor_ogg_int64_t bittrack;
+ tremor_ogg_int64_t samptrack;
- ogg_stream_state os; /* take physical pages, weld into a logical
+ tremor_ogg_stream_state *os; /* take physical pages, weld into a logical
stream of packets */
- vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
- vorbis_block vb; /* local working space for packet->PCM decode */
+ vorbis_dsp_state *vd; /* central working state for the packet->PCM decoder */
ov_callbacks callbacks;
-} OggVorbis_File;
+} TremorOggVorbis_File;
-extern int ov_clear(OggVorbis_File *vf);
-extern int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
-extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
- const char *initial, long ibytes, ov_callbacks callbacks);
+extern int ov_clear(TremorOggVorbis_File *vf);
+extern int ov_open(FILE *f,TremorOggVorbis_File *vf,char *initial,long ibytes);
+extern int ov_open_callbacks(void *datasource, TremorOggVorbis_File *vf,
+ char *initial, long ibytes, ov_callbacks callbacks);
-extern int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
-extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf,
- const char *initial, long ibytes, ov_callbacks callbacks);
-extern int ov_test_open(OggVorbis_File *vf);
+extern int ov_test(FILE *f,TremorOggVorbis_File *vf,char *initial,long ibytes);
+extern int ov_test_callbacks(void *datasource, TremorOggVorbis_File *vf,
+ char *initial, long ibytes, ov_callbacks callbacks);
+extern int ov_test_open(TremorOggVorbis_File *vf);
-extern long ov_bitrate(OggVorbis_File *vf,int i);
-extern long ov_bitrate_instant(OggVorbis_File *vf);
-extern long ov_streams(OggVorbis_File *vf);
-extern long ov_seekable(OggVorbis_File *vf);
-extern long ov_serialnumber(OggVorbis_File *vf,int i);
+extern long ov_bitrate(TremorOggVorbis_File *vf,int i);
+extern long ov_bitrate_instant(TremorOggVorbis_File *vf);
+extern long ov_streams(TremorOggVorbis_File *vf);
+extern long ov_seekable(TremorOggVorbis_File *vf);
+extern long ov_serialnumber(TremorOggVorbis_File *vf,int i);
-extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i);
-extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i);
-extern ogg_int64_t ov_time_total(OggVorbis_File *vf,int i);
+extern tremor_ogg_int64_t ov_raw_total(TremorOggVorbis_File *vf,int i);
+extern tremor_ogg_int64_t ov_pcm_total(TremorOggVorbis_File *vf,int i);
+extern tremor_ogg_int64_t ov_time_total(TremorOggVorbis_File *vf,int i);
-extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos);
-extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos);
-extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos);
-extern int ov_time_seek(OggVorbis_File *vf,ogg_int64_t pos);
-extern int ov_time_seek_page(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_raw_seek(TremorOggVorbis_File *vf,tremor_ogg_int64_t pos);
+extern int ov_pcm_seek(TremorOggVorbis_File *vf,tremor_ogg_int64_t pos);
+extern int ov_pcm_seek_page(TremorOggVorbis_File *vf,tremor_ogg_int64_t pos);
+extern int ov_time_seek(TremorOggVorbis_File *vf,tremor_ogg_int64_t pos);
+extern int ov_time_seek_page(TremorOggVorbis_File *vf,tremor_ogg_int64_t pos);
-extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf);
-extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf);
-extern ogg_int64_t ov_time_tell(OggVorbis_File *vf);
+extern tremor_ogg_int64_t ov_raw_tell(TremorOggVorbis_File *vf);
+extern tremor_ogg_int64_t ov_pcm_tell(TremorOggVorbis_File *vf);
+extern tremor_ogg_int64_t ov_time_tell(TremorOggVorbis_File *vf);
-extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
-extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
+extern vorbis_info *ov_info(TremorOggVorbis_File *vf,int link);
+extern vorbis_comment *ov_comment(TremorOggVorbis_File *vf,int link);
-extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
+extern long ov_read(TremorOggVorbis_File *vf,void *buffer,int length,
int *bitstream);
#ifdef __cplusplus
diff --git a/lib/tremor/ivorbisfile_example.c b/lib/tremor/ivorbisfile_example.c
index 7b0cf109..5c0e6bcc 100644
--- a/lib/tremor/ivorbisfile_example.c
+++ b/lib/tremor/ivorbisfile_example.c
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -32,7 +32,7 @@
char pcmout[4096]; /* take 4k out of the data segment, not the stack */
int main(){
- OggVorbis_File vf;
+ TremorOggVorbis_File vf;
int eof=0;
int current_section;
@@ -69,12 +69,7 @@ int main(){
/* EOF */
eof=1;
} else if (ret < 0) {
- if(ret==OV_EBADLINK){
- fprintf(stderr,"Corrupt bitstream section! Exiting.\n");
- exit(1);
- }
-
- /* some other error in the stream. Not a problem, just reporting it in
+ /* error in the stream. Not a problem, just reporting it in
case we (the app) cares. In this case, we don't. */
} else {
/* we don't bother dealing with sample rate changes, etc, but
diff --git a/lib/tremor/lsp_lookup.h b/lib/tremor/lsp_lookup.h
index 7162392b..3edcab3a 100644
--- a/lib/tremor/lsp_lookup.h
+++ b/lib/tremor/lsp_lookup.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -18,35 +18,7 @@
#ifndef _V_LOOKUP_DATA_H_
#define _V_LOOKUP_DATA_H_
-#include <ogg/os_types.h>
-
-#define FROMdB_LOOKUP_SZ 35
-#define FROMdB2_LOOKUP_SZ 32
-#define FROMdB_SHIFT 5
-#define FROMdB2_SHIFT 3
-#define FROMdB2_MASK 31
-
-static const ogg_int32_t FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={
- 0x003fffff, 0x0028619b, 0x00197a96, 0x0010137a,
- 0x000a24b0, 0x00066666, 0x000409c3, 0x00028c42,
- 0x00019b8c, 0x000103ab, 0x0000a3d7, 0x00006760,
- 0x0000413a, 0x00002928, 0x000019f8, 0x00001062,
- 0x00000a56, 0x00000686, 0x0000041e, 0x00000299,
- 0x000001a3, 0x00000109, 0x000000a7, 0x00000069,
- 0x00000042, 0x0000002a, 0x0000001a, 0x00000011,
- 0x0000000b, 0x00000007, 0x00000004, 0x00000003,
- 0x00000002, 0x00000001, 0x00000001};
-
-static const ogg_int32_t FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={
- 0x000001fc, 0x000001f5, 0x000001ee, 0x000001e7,
- 0x000001e0, 0x000001d9, 0x000001d2, 0x000001cc,
- 0x000001c5, 0x000001bf, 0x000001b8, 0x000001b2,
- 0x000001ac, 0x000001a6, 0x000001a0, 0x0000019a,
- 0x00000194, 0x0000018e, 0x00000188, 0x00000183,
- 0x0000017d, 0x00000178, 0x00000172, 0x0000016d,
- 0x00000168, 0x00000163, 0x0000015e, 0x00000159,
- 0x00000154, 0x0000014f, 0x0000014a, 0x00000145,
-};
+#include "os_types.h"
#define INVSQ_LOOKUP_I_SHIFT 10
#define INVSQ_LOOKUP_I_MASK 1023
@@ -92,7 +64,7 @@ static const long INVSQ_LOOKUP_IDel[64]={
#define COS_LOOKUP_I_SHIFT 9
#define COS_LOOKUP_I_MASK 511
#define COS_LOOKUP_I_SZ 128
-static const ogg_int32_t COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={
+static const tremor_ogg_int32_t COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={
16384, 16379, 16364, 16340,
16305, 16261, 16207, 16143,
16069, 15986, 15893, 15791,
diff --git a/lib/tremor/mapping0.c b/lib/tremor/mapping0.c
index aa03e854..3da185c5 100644
--- a/lib/tremor/mapping0.c
+++ b/lib/tremor/mapping0.c
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -19,101 +19,23 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
-#include <ogg/ogg.h>
+#include "tremor_ogg.h"
+#include "os.h"
#include "ivorbiscodec.h"
#include "mdct.h"
#include "codec_internal.h"
#include "codebook.h"
-#include "window.h"
-#include "registry.h"
#include "misc.h"
-/* simplistic, wasteful way of doing this (unique lookup for each
- mode/submapping); there should be a central repository for
- identical lookups. That will require minor work, so I'm putting it
- off as low priority.
-
- Why a lookup for each backend in a given mode? Because the
- blocksize is set by the mode, and low backend lookups may require
- parameters from other areas of the mode/mapping */
-
-typedef struct {
- vorbis_info_mode *mode;
- vorbis_info_mapping0 *map;
-
- vorbis_look_floor **floor_look;
-
- vorbis_look_residue **residue_look;
-
- vorbis_func_floor **floor_func;
- vorbis_func_residue **residue_func;
-
- int ch;
- long lastframe; /* if a different mode is called, we need to
- invalidate decay */
-} vorbis_look_mapping0;
-
-static void mapping0_free_info(vorbis_info_mapping *i){
- vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i;
+void mapping_clear_info(vorbis_info_mapping *info){
if(info){
+ if(info->chmuxlist)_tremor_ogg_free(info->chmuxlist);
+ if(info->submaplist)_tremor_ogg_free(info->submaplist);
+ if(info->coupling)_tremor_ogg_free(info->coupling);
memset(info,0,sizeof(*info));
- _ogg_free(info);
- }
-}
-
-static void mapping0_free_look(vorbis_look_mapping *look){
- int i;
- vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look;
- if(l){
-
- for(i=0;i<l->map->submaps;i++){
- l->floor_func[i]->free_look(l->floor_look[i]);
- l->residue_func[i]->free_look(l->residue_look[i]);
- }
-
- _ogg_free(l->floor_func);
- _ogg_free(l->residue_func);
- _ogg_free(l->floor_look);
- _ogg_free(l->residue_look);
- memset(l,0,sizeof(*l));
- _ogg_free(l);
}
}
-static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
- vorbis_info_mapping *m){
- int i;
- vorbis_info *vi=vd->vi;
- codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)_ogg_calloc(1,sizeof(*look));
- vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m;
- look->mode=vm;
-
- look->floor_look=(vorbis_look_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_look));
-
- look->residue_look=(vorbis_look_residue **)_ogg_calloc(info->submaps,sizeof(*look->residue_look));
-
- look->floor_func=(vorbis_func_floor **)_ogg_calloc(info->submaps,sizeof(*look->floor_func));
- look->residue_func=(vorbis_func_residue **)_ogg_calloc(info->submaps,sizeof(*look->residue_func));
-
- for(i=0;i<info->submaps;i++){
- int floornum=info->floorsubmap[i];
- int resnum=info->residuesubmap[i];
-
- look->floor_func[i]=_floor_P[ci->floor_type[floornum]];
- look->floor_look[i]=look->floor_func[i]->
- look(vd,vm,ci->floor_param[floornum]);
- look->residue_func[i]=_residue_P[ci->residue_type[resnum]];
- look->residue_look[i]=look->residue_func[i]->
- look(vd,vm,ci->residue_param[resnum]);
-
- }
-
- look->ch=vi->channels;
-
- return(look);
-}
-
static int ilog(unsigned int v){
int ret=0;
if(v)--v;
@@ -125,28 +47,25 @@ static int ilog(unsigned int v){
}
/* also responsible for range checking */
-static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
- int i,b;
- vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)_ogg_calloc(1,sizeof(*info));
+int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi,
+ tremor_oggpack_buffer *opb){
+ int i;
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
memset(info,0,sizeof(*info));
- b=oggpack_read(opb,1);
- if(b<0)goto err_out;
- if(b){
- info->submaps=oggpack_read(opb,4)+1;
- if(info->submaps<=0)goto err_out;
- }else
+ if(tremor_oggpack_read(opb,1))
+ info->submaps=tremor_oggpack_read(opb,4)+1;
+ else
info->submaps=1;
- b=oggpack_read(opb,1);
- if(b<0)goto err_out;
- if(b){
- info->coupling_steps=oggpack_read(opb,8)+1;
- if(info->coupling_steps<=0)goto err_out;
+ if(tremor_oggpack_read(opb,1)){
+ info->coupling_steps=tremor_oggpack_read(opb,8)+1;
+ info->coupling=
+ _tremor_ogg_malloc(info->coupling_steps*sizeof(*info->coupling));
+
for(i=0;i<info->coupling_steps;i++){
- int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels));
- int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels));
+ int testM=info->coupling[i].mag=tremor_oggpack_read(opb,ilog(vi->channels));
+ int testA=info->coupling[i].ang=tremor_oggpack_read(opb,ilog(vi->channels));
if(testM<0 ||
testA<0 ||
@@ -157,72 +76,82 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb)
}
- if(oggpack_read(opb,2)!=0)goto err_out; /* 2,3:reserved */
+ if(tremor_oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */
if(info->submaps>1){
+ info->chmuxlist=_tremor_ogg_malloc(sizeof(*info->chmuxlist)*vi->channels);
for(i=0;i<vi->channels;i++){
- info->chmuxlist[i]=oggpack_read(opb,4);
- if(info->chmuxlist[i]>=info->submaps || info->chmuxlist[i]<0)goto err_out;
+ info->chmuxlist[i]=tremor_oggpack_read(opb,4);
+ if(info->chmuxlist[i]>=info->submaps)goto err_out;
}
}
+
+ info->submaplist=_tremor_ogg_malloc(sizeof(*info->submaplist)*info->submaps);
for(i=0;i<info->submaps;i++){
- int temp=oggpack_read(opb,8);
- if(temp>=ci->times)goto err_out;
- info->floorsubmap[i]=oggpack_read(opb,8);
- if(info->floorsubmap[i]>=ci->floors || info->floorsubmap[i]<0)goto err_out;
- info->residuesubmap[i]=oggpack_read(opb,8);
- if(info->residuesubmap[i]>=ci->residues || info->residuesubmap[i]<0)
- goto err_out;
+ int temp=tremor_oggpack_read(opb,8);
+ info->submaplist[i].floor=tremor_oggpack_read(opb,8);
+ if(info->submaplist[i].floor>=ci->floors)goto err_out;
+ info->submaplist[i].residue=tremor_oggpack_read(opb,8);
+ if(info->submaplist[i].residue>=ci->residues)goto err_out;
}
- return info;
+ return 0;
err_out:
- mapping0_free_info(info);
- return(NULL);
+ mapping_clear_info(info);
+ return -1;
}
-static int seq=0;
-static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
- vorbis_dsp_state *vd=vb->vd;
+int mapping_inverse(vorbis_dsp_state *vd,vorbis_info_mapping *info){
vorbis_info *vi=vd->vi;
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- private_state *b=(private_state *)vd->backend_state;
- vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
- vorbis_info_mapping0 *info=look->map;
int i,j;
- long n=vb->pcmend=ci->blocksizes[vb->W];
-
- ogg_int32_t **pcmbundle=(ogg_int32_t **)alloca(sizeof(*pcmbundle)*vi->channels);
- int *zerobundle=(int *)alloca(sizeof(*zerobundle)*vi->channels);
+ long n=ci->blocksizes[vd->W];
+
+ tremor_ogg_int32_t **pcmbundle=
+ alloca(sizeof(*pcmbundle)*vi->channels);
+ int *zerobundle=
+ alloca(sizeof(*zerobundle)*vi->channels);
+ int *nonzero=
+ alloca(sizeof(*nonzero)*vi->channels);
+ tremor_ogg_int32_t **floormemo=
+ alloca(sizeof(*floormemo)*vi->channels);
- int *nonzero =(int *)alloca(sizeof(*nonzero)*vi->channels);
- void **floormemo=(void **)alloca(sizeof(*floormemo)*vi->channels);
-
- /* time domain information decode (note that applying the
- information would have to happen later; we'll probably add a
- function entry to the harness for that later */
- /* NOT IMPLEMENTED */
-
/* recover the spectral envelope; store it in the PCM vector for now */
for(i=0;i<vi->channels;i++){
- int submap=info->chmuxlist[i];
- floormemo[i]=look->floor_func[submap]->
- inverse1(vb,look->floor_look[submap]);
+ int submap=0;
+ int floorno;
+
+ if(info->submaps>1)
+ submap=info->chmuxlist[i];
+ floorno=info->submaplist[submap].floor;
+
+ if(ci->floor_type[floorno]){
+ /* floor 1 */
+ floormemo[i]=alloca(sizeof(*floormemo[i])*
+ floor1_memosize(ci->floor_param[floorno]));
+ floormemo[i]=floor1_inverse1(vd,ci->floor_param[floorno],floormemo[i]);
+ }else{
+ /* floor 0 */
+ floormemo[i]=alloca(sizeof(*floormemo[i])*
+ floor0_memosize(ci->floor_param[floorno]));
+ floormemo[i]=floor0_inverse1(vd,ci->floor_param[floorno],floormemo[i]);
+ }
+
if(floormemo[i])
nonzero[i]=1;
else
nonzero[i]=0;
- memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
+ memset(vd->work[i],0,sizeof(*vd->work[i])*n/2);
}
/* channel coupling can 'dirty' the nonzero listing */
for(i=0;i<info->coupling_steps;i++){
- if(nonzero[info->coupling_mag[i]] ||
- nonzero[info->coupling_ang[i]]){
- nonzero[info->coupling_mag[i]]=1;
- nonzero[info->coupling_ang[i]]=1;
+ if(nonzero[info->coupling[i].mag] ||
+ nonzero[info->coupling[i].ang]){
+ nonzero[info->coupling[i].mag]=1;
+ nonzero[info->coupling[i].ang]=1;
}
}
@@ -230,31 +159,30 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
for(i=0;i<info->submaps;i++){
int ch_in_bundle=0;
for(j=0;j<vi->channels;j++){
- if(info->chmuxlist[j]==i){
+ if(!info->chmuxlist || info->chmuxlist[j]==i){
if(nonzero[j])
zerobundle[ch_in_bundle]=1;
else
zerobundle[ch_in_bundle]=0;
- pcmbundle[ch_in_bundle++]=vb->pcm[j];
+ pcmbundle[ch_in_bundle++]=vd->work[j];
}
}
- look->residue_func[i]->inverse(vb,look->residue_look[i],
- pcmbundle,zerobundle,ch_in_bundle);
+ res_inverse(vd,ci->residue_param+info->submaplist[i].residue,
+ pcmbundle,zerobundle,ch_in_bundle);
}
//for(j=0;j<vi->channels;j++)
//_analysis_output("coupled",seq+j,vb->pcm[j],-8,n/2,0,0);
-
/* channel coupling */
for(i=info->coupling_steps-1;i>=0;i--){
- ogg_int32_t *pcmM=vb->pcm[info->coupling_mag[i]];
- ogg_int32_t *pcmA=vb->pcm[info->coupling_ang[i]];
+ tremor_ogg_int32_t *pcmM=vd->work[info->coupling[i].mag];
+ tremor_ogg_int32_t *pcmA=vd->work[info->coupling[i].ang];
for(j=0;j<n/2;j++){
- ogg_int32_t mag=pcmM[j];
- ogg_int32_t ang=pcmA[j];
+ tremor_ogg_int32_t mag=pcmM[j];
+ tremor_ogg_int32_t ang=pcmA[j];
if(mag>0)
if(ang>0){
@@ -280,10 +208,21 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
/* compute and apply spectral envelope */
for(i=0;i<vi->channels;i++){
- ogg_int32_t *pcm=vb->pcm[i];
- int submap=info->chmuxlist[i];
- look->floor_func[submap]->
- inverse2(vb,look->floor_look[submap],floormemo[i],pcm);
+ tremor_ogg_int32_t *pcm=vd->work[i];
+ int submap=0;
+ int floorno;
+
+ if(info->submaps>1)
+ submap=info->chmuxlist[i];
+ floorno=info->submaplist[submap].floor;
+
+ if(ci->floor_type[floorno]){
+ /* floor 1 */
+ floor1_inverse2(vd,ci->floor_param[floorno],floormemo[i],pcm);
+ }else{
+ /* floor 0 */
+ floor0_inverse2(vd,ci->floor_param[floorno],floormemo[i],pcm);
+ }
}
//for(j=0;j<vi->channels;j++)
@@ -291,38 +230,12 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
/* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
/* only MDCT right now.... */
- for(i=0;i<vi->channels;i++){
- ogg_int32_t *pcm=vb->pcm[i];
- mdct_backward(n,pcm,pcm);
- }
+ for(i=0;i<vi->channels;i++)
+ mdct_backward(n,vd->work[i]);
//for(j=0;j<vi->channels;j++)
//_analysis_output("imdct",seq+j,vb->pcm[j],-24,n,0,0);
- /* window the data */
- for(i=0;i<vi->channels;i++){
- ogg_int32_t *pcm=vb->pcm[i];
- if(nonzero[i])
- _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
- else
- for(j=0;j<n;j++)
- pcm[j]=0;
-
- }
-
- //for(j=0;j<vi->channels;j++)
- //_analysis_output("window",seq+j,vb->pcm[j],-24,n,0,0);
-
- seq+=vi->channels;
/* all done! */
return(0);
}
-
-/* export hooks */
-vorbis_func_mapping mapping0_exportbundle={
- &mapping0_unpack,
- &mapping0_look,
- &mapping0_free_info,
- &mapping0_free_look,
- &mapping0_inverse
-};
diff --git a/lib/tremor/mdct.c b/lib/tremor/mdct.c
index 2aed62c5..40f53877 100644
--- a/lib/tremor/mdct.c
+++ b/lib/tremor/mdct.c
@@ -1,19 +1,19 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
function: normalized modified discrete cosine transform
power of two length transform only [64 <= n ]
- last mod: $Id$
+ last mod: $Id: mdct.c,v 1.9.6.5 2003/04/29 04:03:27 xiphmont Exp $
Original algorithm adapted long ago from _The use of multirate filter
banks for coding of high quality digital audio_, by T. Sporer,
@@ -33,23 +33,62 @@
********************************************************************/
#include "ivorbiscodec.h"
-#include "codebook.h"
+#include "os.h"
#include "misc.h"
#include "mdct.h"
#include "mdct_lookup.h"
+STIN void presymmetry(DATA_TYPE *in,int n2,int step){
+ DATA_TYPE *aX;
+ DATA_TYPE *bX;
+ LOOKUP_T *T;
+ int n4=n2>>1;
+
+ aX = in+n2-3;
+ T = sincos_lookup0;
+
+ do{
+ REG_TYPE r0= aX[0];
+ REG_TYPE r2= aX[2];
+ XPROD31( r0, r2, T[0], T[1], &aX[0], &aX[2] ); T+=step;
+ aX-=4;
+ }while(aX>=in+n4);
+ do{
+ REG_TYPE r0= aX[0];
+ REG_TYPE r2= aX[2];
+ XPROD31( r0, r2, T[1], T[0], &aX[0], &aX[2] ); T-=step;
+ aX-=4;
+ }while(aX>=in);
+
+ aX = in+n2-4;
+ bX = in;
+ T = sincos_lookup0;
+ do{
+ REG_TYPE ri0= aX[0];
+ REG_TYPE ri2= aX[2];
+ REG_TYPE ro0= bX[0];
+ REG_TYPE ro2= bX[2];
+
+ XNPROD31( ro2, ro0, T[1], T[0], &aX[0], &aX[2] ); T+=step;
+ XNPROD31( ri2, ri0, T[0], T[1], &bX[0], &bX[2] );
+
+ aX-=4;
+ bX+=4;
+ }while(aX>=in+n4);
+
+}
/* 8 point butterfly (in place) */
STIN void mdct_butterfly_8(DATA_TYPE *x){
- REG_TYPE r0 = x[4] + x[0];
- REG_TYPE r1 = x[4] - x[0];
- REG_TYPE r2 = x[5] + x[1];
- REG_TYPE r3 = x[5] - x[1];
- REG_TYPE r4 = x[6] + x[2];
- REG_TYPE r5 = x[6] - x[2];
- REG_TYPE r6 = x[7] + x[3];
- REG_TYPE r7 = x[7] - x[3];
+ REG_TYPE r0 = x[0] + x[1];
+ REG_TYPE r1 = x[0] - x[1];
+ REG_TYPE r2 = x[2] + x[3];
+ REG_TYPE r3 = x[2] - x[3];
+ REG_TYPE r4 = x[4] + x[5];
+ REG_TYPE r5 = x[4] - x[5];
+ REG_TYPE r6 = x[6] + x[7];
+ REG_TYPE r7 = x[6] - x[7];
x[0] = r5 + r3;
x[1] = r7 - r1;
@@ -64,29 +103,25 @@ STIN void mdct_butterfly_8(DATA_TYPE *x){
/* 16 point butterfly (in place, 4 register) */
STIN void mdct_butterfly_16(DATA_TYPE *x){
-
- REG_TYPE r0, r1;
-
- r0 = x[ 0] - x[ 8]; x[ 8] += x[ 0];
- r1 = x[ 1] - x[ 9]; x[ 9] += x[ 1];
- x[ 0] = MULT31((r0 + r1) , cPI2_8);
- x[ 1] = MULT31((r1 - r0) , cPI2_8);
- MB();
-
- r0 = x[10] - x[ 2]; x[10] += x[ 2];
- r1 = x[ 3] - x[11]; x[11] += x[ 3];
- x[ 2] = r1; x[ 3] = r0;
- MB();
-
- r0 = x[12] - x[ 4]; x[12] += x[ 4];
- r1 = x[13] - x[ 5]; x[13] += x[ 5];
- x[ 4] = MULT31((r0 - r1) , cPI2_8);
- x[ 5] = MULT31((r0 + r1) , cPI2_8);
+
+ REG_TYPE r0, r1, r2, r3;
+
+ r0 = x[ 8] - x[ 9]; x[ 8] += x[ 9];
+ r1 = x[10] - x[11]; x[10] += x[11];
+ r2 = x[ 1] - x[ 0]; x[ 9] = x[ 1] + x[0];
+ r3 = x[ 3] - x[ 2]; x[11] = x[ 3] + x[2];
+ x[ 0] = MULT31((r0 - r1) , cPI2_8);
+ x[ 1] = MULT31((r2 + r3) , cPI2_8);
+ x[ 2] = MULT31((r0 + r1) , cPI2_8);
+ x[ 3] = MULT31((r3 - r2) , cPI2_8);
MB();
- r0 = x[14] - x[ 6]; x[14] += x[ 6];
- r1 = x[15] - x[ 7]; x[15] += x[ 7];
- x[ 6] = r0; x[ 7] = r1;
+ r2 = x[12] - x[13]; x[12] += x[13];
+ r3 = x[14] - x[15]; x[14] += x[15];
+ r0 = x[ 4] - x[ 5]; x[13] = x[ 5] + x[ 4];
+ r1 = x[ 7] - x[ 6]; x[15] = x[ 7] + x[ 6];
+ x[ 4] = r2; x[ 5] = r1;
+ x[ 6] = r3; x[ 7] = r0;
MB();
mdct_butterfly_8(x);
@@ -96,48 +131,40 @@ STIN void mdct_butterfly_16(DATA_TYPE *x){
/* 32 point butterfly (in place, 4 register) */
STIN void mdct_butterfly_32(DATA_TYPE *x){
- REG_TYPE r0, r1;
-
- r0 = x[30] - x[14]; x[30] += x[14];
- r1 = x[31] - x[15]; x[31] += x[15];
- x[14] = r0; x[15] = r1;
- MB();
-
- r0 = x[28] - x[12]; x[28] += x[12];
- r1 = x[29] - x[13]; x[29] += x[13];
- XNPROD31( r0, r1, cPI1_8, cPI3_8, &x[12], &x[13] );
- MB();
-
- r0 = x[26] - x[10]; x[26] += x[10];
- r1 = x[27] - x[11]; x[27] += x[11];
- x[10] = MULT31((r0 - r1) , cPI2_8);
- x[11] = MULT31((r0 + r1) , cPI2_8);
- MB();
-
- r0 = x[24] - x[ 8]; x[24] += x[ 8];
- r1 = x[25] - x[ 9]; x[25] += x[ 9];
- XNPROD31( r0, r1, cPI3_8, cPI1_8, &x[ 8], &x[ 9] );
- MB();
+ REG_TYPE r0, r1, r2, r3;
- r0 = x[22] - x[ 6]; x[22] += x[ 6];
- r1 = x[ 7] - x[23]; x[23] += x[ 7];
- x[ 6] = r1; x[ 7] = r0;
+ r0 = x[16] - x[17]; x[16] += x[17];
+ r1 = x[18] - x[19]; x[18] += x[19];
+ r2 = x[ 1] - x[ 0]; x[17] = x[ 1] + x[ 0];
+ r3 = x[ 3] - x[ 2]; x[19] = x[ 3] + x[ 2];
+ XNPROD31( r0, r1, cPI3_8, cPI1_8, &x[ 0], &x[ 2] );
+ XPROD31 ( r2, r3, cPI1_8, cPI3_8, &x[ 1], &x[ 3] );
MB();
- r0 = x[ 4] - x[20]; x[20] += x[ 4];
- r1 = x[ 5] - x[21]; x[21] += x[ 5];
- XPROD31 ( r0, r1, cPI3_8, cPI1_8, &x[ 4], &x[ 5] );
+ r0 = x[20] - x[21]; x[20] += x[21];
+ r1 = x[22] - x[23]; x[22] += x[23];
+ r2 = x[ 5] - x[ 4]; x[21] = x[ 5] + x[ 4];
+ r3 = x[ 7] - x[ 6]; x[23] = x[ 7] + x[ 6];
+ x[ 4] = MULT31((r0 - r1) , cPI2_8);
+ x[ 5] = MULT31((r3 + r2) , cPI2_8);
+ x[ 6] = MULT31((r0 + r1) , cPI2_8);
+ x[ 7] = MULT31((r3 - r2) , cPI2_8);
MB();
- r0 = x[ 2] - x[18]; x[18] += x[ 2];
- r1 = x[ 3] - x[19]; x[19] += x[ 3];
- x[ 2] = MULT31((r1 + r0) , cPI2_8);
- x[ 3] = MULT31((r1 - r0) , cPI2_8);
+ r0 = x[24] - x[25]; x[24] += x[25];
+ r1 = x[26] - x[27]; x[26] += x[27];
+ r2 = x[ 9] - x[ 8]; x[25] = x[ 9] + x[ 8];
+ r3 = x[11] - x[10]; x[27] = x[11] + x[10];
+ XNPROD31( r0, r1, cPI1_8, cPI3_8, &x[ 8], &x[10] );
+ XPROD31 ( r2, r3, cPI3_8, cPI1_8, &x[ 9], &x[11] );
MB();
- r0 = x[ 0] - x[16]; x[16] += x[ 0];
- r1 = x[ 1] - x[17]; x[17] += x[ 1];
- XPROD31 ( r0, r1, cPI1_8, cPI3_8, &x[ 0], &x[ 1] );
+ r0 = x[28] - x[29]; x[28] += x[29];
+ r1 = x[30] - x[31]; x[30] += x[31];
+ r2 = x[12] - x[13]; x[29] = x[13] + x[12];
+ r3 = x[15] - x[14]; x[31] = x[15] + x[14];
+ x[12] = r0; x[13] = r3;
+ x[14] = r1; x[15] = r2;
MB();
mdct_butterfly_16(x);
@@ -147,87 +174,30 @@ STIN void mdct_butterfly_32(DATA_TYPE *x){
/* N/stage point generic N stage butterfly (in place, 2 register) */
STIN void mdct_butterfly_generic(DATA_TYPE *x,int points,int step){
- LOOKUP_T *T = sincos_lookup0;
- DATA_TYPE *x1 = x + points - 8;
- DATA_TYPE *x2 = x + (points>>1) - 8;
- REG_TYPE r0;
- REG_TYPE r1;
-
- do{
- r0 = x1[6] - x2[6]; x1[6] += x2[6];
- r1 = x2[7] - x1[7]; x1[7] += x2[7];
- XPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T+=step;
-
- r0 = x1[4] - x2[4]; x1[4] += x2[4];
- r1 = x2[5] - x1[5]; x1[5] += x2[5];
- XPROD31( r1, r0, T[0], T[1], &x2[4], &x2[5] ); T+=step;
+ LOOKUP_T *T = sincos_lookup0;
+ DATA_TYPE *x1 = x + points - 4;
+ DATA_TYPE *x2 = x + (points>>1) - 4;
+ REG_TYPE r0, r1, r2, r3;
- r0 = x1[2] - x2[2]; x1[2] += x2[2];
- r1 = x2[3] - x1[3]; x1[3] += x2[3];
- XPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T+=step;
-
- r0 = x1[0] - x2[0]; x1[0] += x2[0];
- r1 = x2[1] - x1[1]; x1[1] += x2[1];
- XPROD31( r1, r0, T[0], T[1], &x2[0], &x2[1] ); T+=step;
-
- x1-=8; x2-=8;
- }while(T<sincos_lookup0+1024);
- do{
- r0 = x1[6] - x2[6]; x1[6] += x2[6];
- r1 = x1[7] - x2[7]; x1[7] += x2[7];
- XNPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T-=step;
-
- r0 = x1[4] - x2[4]; x1[4] += x2[4];
- r1 = x1[5] - x2[5]; x1[5] += x2[5];
- XNPROD31( r0, r1, T[0], T[1], &x2[4], &x2[5] ); T-=step;
-
- r0 = x1[2] - x2[2]; x1[2] += x2[2];
- r1 = x1[3] - x2[3]; x1[3] += x2[3];
- XNPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T-=step;
-
- r0 = x1[0] - x2[0]; x1[0] += x2[0];
- r1 = x1[1] - x2[1]; x1[1] += x2[1];
- XNPROD31( r0, r1, T[0], T[1], &x2[0], &x2[1] ); T-=step;
-
- x1-=8; x2-=8;
- }while(T>sincos_lookup0);
do{
- r0 = x2[6] - x1[6]; x1[6] += x2[6];
- r1 = x2[7] - x1[7]; x1[7] += x2[7];
- XPROD31( r0, r1, T[0], T[1], &x2[6], &x2[7] ); T+=step;
-
- r0 = x2[4] - x1[4]; x1[4] += x2[4];
- r1 = x2[5] - x1[5]; x1[5] += x2[5];
- XPROD31( r0, r1, T[0], T[1], &x2[4], &x2[5] ); T+=step;
-
- r0 = x2[2] - x1[2]; x1[2] += x2[2];
- r1 = x2[3] - x1[3]; x1[3] += x2[3];
- XPROD31( r0, r1, T[0], T[1], &x2[2], &x2[3] ); T+=step;
-
- r0 = x2[0] - x1[0]; x1[0] += x2[0];
- r1 = x2[1] - x1[1]; x1[1] += x2[1];
- XPROD31( r0, r1, T[0], T[1], &x2[0], &x2[1] ); T+=step;
-
- x1-=8; x2-=8;
+ r0 = x1[0] - x1[1]; x1[0] += x1[1];
+ r1 = x1[3] - x1[2]; x1[2] += x1[3];
+ r2 = x2[1] - x2[0]; x1[1] = x2[1] + x2[0];
+ r3 = x2[3] - x2[2]; x1[3] = x2[3] + x2[2];
+ XPROD31( r1, r0, T[0], T[1], &x2[0], &x2[2] );
+ XPROD31( r2, r3, T[0], T[1], &x2[1], &x2[3] ); T+=step;
+ x1-=4;
+ x2-=4;
}while(T<sincos_lookup0+1024);
do{
- r0 = x1[6] - x2[6]; x1[6] += x2[6];
- r1 = x2[7] - x1[7]; x1[7] += x2[7];
- XNPROD31( r1, r0, T[0], T[1], &x2[6], &x2[7] ); T-=step;
-
- r0 = x1[4] - x2[4]; x1[4] += x2[4];
- r1 = x2[5] - x1[5]; x1[5] += x2[5];
- XNPROD31( r1, r0, T[0], T[1], &x2[4], &x2[5] ); T-=step;
-
- r0 = x1[2] - x2[2]; x1[2] += x2[2];
- r1 = x2[3] - x1[3]; x1[3] += x2[3];
- XNPROD31( r1, r0, T[0], T[1], &x2[2], &x2[3] ); T-=step;
-
- r0 = x1[0] - x2[0]; x1[0] += x2[0];
- r1 = x2[1] - x1[1]; x1[1] += x2[1];
- XNPROD31( r1, r0, T[0], T[1], &x2[0], &x2[1] ); T-=step;
-
- x1-=8; x2-=8;
+ r0 = x1[0] - x1[1]; x1[0] += x1[1];
+ r1 = x1[2] - x1[3]; x1[2] += x1[3];
+ r2 = x2[0] - x2[1]; x1[1] = x2[1] + x2[0];
+ r3 = x2[3] - x2[2]; x1[3] = x2[3] + x2[2];
+ XNPROD31( r0, r1, T[0], T[1], &x2[0], &x2[2] );
+ XNPROD31( r3, r2, T[0], T[1], &x2[1], &x2[3] ); T-=step;
+ x1-=4;
+ x2-=4;
}while(T>sincos_lookup0);
}
@@ -235,15 +205,14 @@ STIN void mdct_butterflies(DATA_TYPE *x,int points,int shift){
int stages=8-shift;
int i,j;
-
+
for(i=0;--stages>0;i++){
for(j=0;j<(1<<i);j++)
mdct_butterfly_generic(x+(points>>i)*j,points>>i,4<<(i+shift));
}
-
+
for(j=0;j<points;j+=32)
mdct_butterfly_32(x+j);
-
}
static unsigned char bitrev[16]={0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
@@ -252,259 +221,266 @@ STIN int bitrev12(int x){
return bitrev[x>>8]|(bitrev[(x&0x0f0)>>4]<<4)|(((int)bitrev[x&0x00f])<<8);
}
-STIN void mdct_bitreverse(DATA_TYPE *x,int n,int step,int shift){
-
+STIN void mdct_bitreverse(DATA_TYPE *x,int n,int shift){
int bit = 0;
+ DATA_TYPE *w = x+(n>>1);
+
+ do{
+ DATA_TYPE b = bitrev12(bit++);
+ DATA_TYPE *xx = x + (b>>shift);
+ REG_TYPE r;
+
+ w -= 2;
+
+ if(w>xx){
+
+ r = xx[0];
+ xx[0] = w[0];
+ w[0] = r;
+
+ r = xx[1];
+ xx[1] = w[1];
+ w[1] = r;
+ }
+ }while(w>x);
+}
+
+STIN void mdct_step7(DATA_TYPE *x,int n,int step){
DATA_TYPE *w0 = x;
- DATA_TYPE *w1 = x = w0+(n>>1);
+ DATA_TYPE *w1 = x+(n>>1);
LOOKUP_T *T = (step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1;
LOOKUP_T *Ttop = T+1024;
- DATA_TYPE r2;
-
+ REG_TYPE r0, r1, r2, r3;
+
do{
- DATA_TYPE r3 = bitrev12(bit++);
- DATA_TYPE *x0 = x + ((r3 ^ 0xfff)>>shift) -1;
- DATA_TYPE *x1 = x + (r3>>shift);
+ w1 -= 2;
- REG_TYPE r0 = x0[0] + x1[0];
- REG_TYPE r1 = x1[1] - x0[1];
+ r0 = w0[0] + w1[0];
+ r1 = w1[1] - w0[1];
+ r2 = MULT32(r0, T[1]) + MULT32(r1, T[0]);
+ r3 = MULT32(r1, T[1]) - MULT32(r0, T[0]);
+ T+=step;
- XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step;
-
- w1 -= 4;
-
- r0 = (x0[1] + x1[1])>>1;
- r1 = (x0[0] - x1[0])>>1;
+ r0 = (w0[1] + w1[1])>>1;
+ r1 = (w0[0] - w1[0])>>1;
w0[0] = r0 + r2;
w0[1] = r1 + r3;
- w1[2] = r0 - r2;
- w1[3] = r3 - r1;
-
- r3 = bitrev12(bit++);
- x0 = x + ((r3 ^ 0xfff)>>shift) -1;
- x1 = x + (r3>>shift);
-
- r0 = x0[0] + x1[0];
- r1 = x1[1] - x0[1];
-
- XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step;
-
- r0 = (x0[1] + x1[1])>>1;
- r1 = (x0[0] - x1[0])>>1;
- w0[2] = r0 + r2;
- w0[3] = r1 + r3;
w1[0] = r0 - r2;
w1[1] = r3 - r1;
- w0 += 4;
+ w0 += 2;
}while(T<Ttop);
do{
- DATA_TYPE r3 = bitrev12(bit++);
- DATA_TYPE *x0 = x + ((r3 ^ 0xfff)>>shift) -1;
- DATA_TYPE *x1 = x + (r3>>shift);
-
- REG_TYPE r0 = x0[0] + x1[0];
- REG_TYPE r1 = x1[1] - x0[1];
+ w1 -= 2;
- T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 );
+ r0 = w0[0] + w1[0];
+ r1 = w1[1] - w0[1];
+ T-=step;
+ r2 = MULT32(r0, T[0]) + MULT32(r1, T[1]);
+ r3 = MULT32(r1, T[0]) - MULT32(r0, T[1]);
- w1 -= 4;
-
- r0 = (x0[1] + x1[1])>>1;
- r1 = (x0[0] - x1[0])>>1;
+ r0 = (w0[1] + w1[1])>>1;
+ r1 = (w0[0] - w1[0])>>1;
w0[0] = r0 + r2;
w0[1] = r1 + r3;
- w1[2] = r0 - r2;
- w1[3] = r3 - r1;
-
- r3 = bitrev12(bit++);
- x0 = x + ((r3 ^ 0xfff)>>shift) -1;
- x1 = x + (r3>>shift);
-
- r0 = x0[0] + x1[0];
- r1 = x1[1] - x0[1];
-
- T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 );
-
- r0 = (x0[1] + x1[1])>>1;
- r1 = (x0[0] - x1[0])>>1;
- w0[2] = r0 + r2;
- w0[3] = r1 + r3;
w1[0] = r0 - r2;
w1[1] = r3 - r1;
- w0 += 4;
+ w0 += 2;
}while(w0<w1);
}
-void mdct_backward(int n, DATA_TYPE *in, DATA_TYPE *out){
- int n2=n>>1;
- int n4=n>>2;
- DATA_TYPE *iX;
- DATA_TYPE *oX;
+STIN void mdct_step8(DATA_TYPE *x, int n, int step){
LOOKUP_T *T;
LOOKUP_T *V;
+ DATA_TYPE *iX =x+(n>>1);
+ step>>=2;
+
+ switch(step) {
+ default:
+ T=(step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1;
+ do{
+ REG_TYPE r0 = x[0];
+ REG_TYPE r1 = -x[1];
+ XPROD31( r0, r1, T[0], T[1], x, x+1); T+=step;
+ x +=2;
+ }while(x<iX);
+ break;
+
+ case 1:
+ {
+ /* linear interpolation between table values: offset=0.5, step=1 */
+ REG_TYPE t0,t1,v0,v1,r0,r1;
+ T = sincos_lookup0;
+ V = sincos_lookup1;
+ t0 = (*T++)>>1;
+ t1 = (*T++)>>1;
+ do{
+ r0 = x[0];
+ r1 = -x[1];
+ t0 += (v0 = (*V++)>>1);
+ t1 += (v1 = (*V++)>>1);
+ XPROD31( r0, r1, t0, t1, x, x+1 );
+
+ r0 = x[2];
+ r1 = -x[3];
+ v0 += (t0 = (*T++)>>1);
+ v1 += (t1 = (*T++)>>1);
+ XPROD31( r0, r1, v0, v1, x+2, x+3 );
+
+ x += 4;
+ }while(x<iX);
+ break;
+ }
+
+ case 0:
+ {
+ /* linear interpolation between table values: offset=0.25, step=0.5 */
+ REG_TYPE t0,t1,v0,v1,q0,q1,r0,r1;
+ T = sincos_lookup0;
+ V = sincos_lookup1;
+ t0 = *T++;
+ t1 = *T++;
+ do{
+
+
+ v0 = *V++;
+ v1 = *V++;
+ t0 += (q0 = (v0-t0)>>2);
+ t1 += (q1 = (v1-t1)>>2);
+ r0 = x[0];
+ r1 = -x[1];
+ XPROD31( r0, r1, t0, t1, x, x+1 );
+ t0 = v0-q0;
+ t1 = v1-q1;
+ r0 = x[2];
+ r1 = -x[3];
+ XPROD31( r0, r1, t0, t1, x+2, x+3 );
+
+ t0 = *T++;
+ t1 = *T++;
+ v0 += (q0 = (t0-v0)>>2);
+ v1 += (q1 = (t1-v1)>>2);
+ r0 = x[4];
+ r1 = -x[5];
+ XPROD31( r0, r1, v0, v1, x+4, x+5 );
+ v0 = t0-q0;
+ v1 = t1-q1;
+ r0 = x[6];
+ r1 = -x[7];
+ XPROD31( r0, r1, v0, v1, x+5, x+6 );
+
+ x+=8;
+ }while(x<iX);
+ break;
+ }
+ }
+}
+
+/* partial; doesn't perform last-step deinterleave/unrolling. That
+ can be done more efficiently during pcm output */
+void mdct_backward(int n, DATA_TYPE *in){
int shift;
int step;
-
- for (shift=6;!(n&(1<<shift));shift++);
+
+ for (shift=4;!(n&(1<<shift));shift++);
shift=13-shift;
step=2<<shift;
- /* rotate */
-
- iX = in+n2-7;
- oX = out+n2+n4;
- T = sincos_lookup0;
-
- do{
- oX-=4;
- XPROD31( iX[4], iX[6], T[0], T[1], &oX[2], &oX[3] ); T+=step;
- XPROD31( iX[0], iX[2], T[0], T[1], &oX[0], &oX[1] ); T+=step;
- iX-=8;
- }while(iX>=in+n4);
- do{
- oX-=4;
- XPROD31( iX[4], iX[6], T[1], T[0], &oX[2], &oX[3] ); T-=step;
- XPROD31( iX[0], iX[2], T[1], T[0], &oX[0], &oX[1] ); T-=step;
- iX-=8;
- }while(iX>=in);
-
- iX = in+n2-8;
- oX = out+n2+n4;
- T = sincos_lookup0;
-
- do{
- T+=step; XNPROD31( iX[6], iX[4], T[0], T[1], &oX[0], &oX[1] );
- T+=step; XNPROD31( iX[2], iX[0], T[0], T[1], &oX[2], &oX[3] );
- iX-=8;
- oX+=4;
- }while(iX>=in+n4);
- do{
- T-=step; XNPROD31( iX[6], iX[4], T[1], T[0], &oX[0], &oX[1] );
- T-=step; XNPROD31( iX[2], iX[0], T[1], T[0], &oX[2], &oX[3] );
- iX-=8;
- oX+=4;
- }while(iX>=in);
+ presymmetry(in,n>>1,step);
+ mdct_butterflies(in,n>>1,shift);
+ mdct_bitreverse(in,n,shift);
+ mdct_step7(in,n,step);
+ mdct_step8(in,n,step);
+}
- mdct_butterflies(out+n2,n2,shift);
- mdct_bitreverse(out,n,step,shift);
+void mdct_shift_right(int n, DATA_TYPE *in, DATA_TYPE *right){
+ int i;
+ n>>=2;
+ in+=1;
- /* rotate + window */
+ for(i=0;i<n;i++)
+ right[i]=in[i<<1];
+}
- step>>=2;
- {
- DATA_TYPE *oX1=out+n2+n4;
- DATA_TYPE *oX2=out+n2+n4;
- DATA_TYPE *iX =out;
-
- switch(step) {
- default: {
- T=(step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1;
- do{
- oX1-=4;
- XPROD31( iX[0], -iX[1], T[0], T[1], &oX1[3], &oX2[0] ); T+=step;
- XPROD31( iX[2], -iX[3], T[0], T[1], &oX1[2], &oX2[1] ); T+=step;
- XPROD31( iX[4], -iX[5], T[0], T[1], &oX1[1], &oX2[2] ); T+=step;
- XPROD31( iX[6], -iX[7], T[0], T[1], &oX1[0], &oX2[3] ); T+=step;
- oX2+=4;
- iX+=8;
- }while(iX<oX1);
- break;
- }
-
- case 1: {
- /* linear interpolation between table values: offset=0.5, step=1 */
- REG_TYPE t0,t1,v0,v1;
- T = sincos_lookup0;
- V = sincos_lookup1;
- t0 = (*T++)>>1;
- t1 = (*T++)>>1;
- do{
- oX1-=4;
-
- t0 += (v0 = (*V++)>>1);
- t1 += (v1 = (*V++)>>1);
- XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] );
- v0 += (t0 = (*T++)>>1);
- v1 += (t1 = (*T++)>>1);
- XPROD31( iX[2], -iX[3], v0, v1, &oX1[2], &oX2[1] );
- t0 += (v0 = (*V++)>>1);
- t1 += (v1 = (*V++)>>1);
- XPROD31( iX[4], -iX[5], t0, t1, &oX1[1], &oX2[2] );
- v0 += (t0 = (*T++)>>1);
- v1 += (t1 = (*T++)>>1);
- XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] );
-
- oX2+=4;
- iX+=8;
- }while(iX<oX1);
- break;
- }
-
- case 0: {
- /* linear interpolation between table values: offset=0.25, step=0.5 */
- REG_TYPE t0,t1,v0,v1,q0,q1;
- T = sincos_lookup0;
- V = sincos_lookup1;
- t0 = *T++;
- t1 = *T++;
- do{
- oX1-=4;
-
- v0 = *V++;
- v1 = *V++;
- t0 += (q0 = (v0-t0)>>2);
- t1 += (q1 = (v1-t1)>>2);
- XPROD31( iX[0], -iX[1], t0, t1, &oX1[3], &oX2[0] );
- t0 = v0-q0;
- t1 = v1-q1;
- XPROD31( iX[2], -iX[3], t0, t1, &oX1[2], &oX2[1] );
-
- t0 = *T++;
- t1 = *T++;
- v0 += (q0 = (t0-v0)>>2);
- v1 += (q1 = (t1-v1)>>2);
- XPROD31( iX[4], -iX[5], v0, v1, &oX1[1], &oX2[2] );
- v0 = t0-q0;
- v1 = t1-q1;
- XPROD31( iX[6], -iX[7], v0, v1, &oX1[0], &oX2[3] );
-
- oX2+=4;
- iX+=8;
- }while(iX<oX1);
- break;
- }
+void mdct_unroll_lap(int n0,int n1,
+ int lW,int W,
+ DATA_TYPE *in,
+ DATA_TYPE *right,
+ LOOKUP_T *w0,
+ LOOKUP_T *w1,
+ tremor_ogg_int16_t *out,
+ int step,
+ int start, /* samples, this frame */
+ int end /* samples, this frame */){
+
+ DATA_TYPE *l=in+(W&&lW ? n1>>1 : n0>>1);
+ DATA_TYPE *r=right+(lW ? n1>>2 : n0>>2);
+ DATA_TYPE *post;
+ LOOKUP_T *wR=(W && lW ? w1+(n1>>1) : w0+(n0>>1));
+ LOOKUP_T *wL=(W && lW ? w1 : w0 );
+
+ int preLap=(lW && !W ? (n1>>2)-(n0>>2) : 0 );
+ int halfLap=(lW && W ? (n1>>2) : (n0>>2) );
+ int postLap=(!lW && W ? (n1>>2)-(n0>>2) : 0 );
+ int n,off;
+
+ /* preceeding direct-copy lapping from previous frame, if any */
+ if(preLap){
+ n = (end<preLap?end:preLap);
+ off = (start<preLap?start:preLap);
+ post = r-n;
+ r -= off;
+ start -= off;
+ end -= n;
+ while(r>post){
+ *out = CLIP_TO_15((*--r)>>9);
+ out+=step;
}
+ }
+
+ /* cross-lap; two halves due to wrap-around */
+ n = (end<halfLap?end:halfLap);
+ off = (start<halfLap?start:halfLap);
+ post = r-n;
+ r -= off;
+ l -= off*2;
+ start -= off;
+ wR -= off;
+ wL += off;
+ end -= n;
+ while(r>post){
+ l-=2;
+ *out = CLIP_TO_15((MULT31(*--r,*--wR) + MULT31(*l,*wL++))>>9);
+ out+=step;
+ }
- iX=out+n2+n4;
- oX1=out+n4;
- oX2=oX1;
-
- do{
- oX1-=4;
- iX-=4;
-
- oX2[0] = -(oX1[3] = iX[3]);
- oX2[1] = -(oX1[2] = iX[2]);
- oX2[2] = -(oX1[1] = iX[1]);
- oX2[3] = -(oX1[0] = iX[0]);
-
- oX2+=4;
- }while(oX2<iX);
-
- iX=out+n2+n4;
- oX1=out+n2+n4;
- oX2=out+n2;
+ n = (end<halfLap?end:halfLap);
+ off = (start<halfLap?start:halfLap);
+ post = r+n;
+ r += off;
+ l += off*2;
+ start -= off;
+ end -= n;
+ wR -= off;
+ wL += off;
+ while(r<post){
+ *out = CLIP_TO_15((MULT31(*r++,*--wR) - MULT31(*l,*wL++))>>9);
+ out+=step;
+ l+=2;
+ }
- do{
- oX1-=4;
- oX1[0]= iX[3];
- oX1[1]= iX[2];
- oX1[2]= iX[1];
- oX1[3]= iX[0];
- iX+=4;
- }while(oX1>oX2);
+ /* preceeding direct-copy lapping from previous frame, if any */
+ if(postLap){
+ n = (end<postLap?end:postLap);
+ off = (start<postLap?start:postLap);
+ post = l+n*2;
+ l += off*2;
+ while(l<post){
+ *out = CLIP_TO_15((-*l)>>9);
+ out+=step;
+ l+=2;
+ }
}
}
diff --git a/lib/tremor/mdct.h b/lib/tremor/mdct.h
index 6d889072..3ddb8495 100644
--- a/lib/tremor/mdct.h
+++ b/lib/tremor/mdct.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -21,8 +21,8 @@
#include "ivorbiscodec.h"
#include "misc.h"
-#define DATA_TYPE ogg_int32_t
-#define REG_TYPE register ogg_int32_t
+#define DATA_TYPE tremor_ogg_int32_t
+#define REG_TYPE register tremor_ogg_int32_t
#ifdef _LOW_ACCURACY_
#define cPI3_8 (0x0062)
@@ -34,8 +34,15 @@
#define cPI1_8 (0x7641af3d)
#endif
-extern void mdct_forward(int n, DATA_TYPE *in, DATA_TYPE *out);
-extern void mdct_backward(int n, DATA_TYPE *in, DATA_TYPE *out);
+extern void mdct_backward(int n, DATA_TYPE *in);
+extern void mdct_shift_right(int n, DATA_TYPE *in, DATA_TYPE *right);
+extern void mdct_unroll_lap(int n0,int n1,
+ int lW,int W,
+ DATA_TYPE *in,DATA_TYPE *right,
+ LOOKUP_T *w0,LOOKUP_T *w1,
+ tremor_ogg_int16_t *out,
+ int step,
+ int start,int end /* samples, this frame */);
#endif
diff --git a/lib/tremor/mdct_lookup.h b/lib/tremor/mdct_lookup.h
index ee4f101c..16a988e4 100644
--- a/lib/tremor/mdct_lookup.h
+++ b/lib/tremor/mdct_lookup.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -15,10 +15,10 @@
********************************************************************/
-#include "misc.h"
+#include "os_types.h"
/* {sin(2*i*PI/4096), cos(2*i*PI/4096)}, with i = 0 to 512 */
-static const LOOKUP_T sincos_lookup0[1026] = {
+static LOOKUP_T sincos_lookup0[1026] = {
X(0x00000000), X(0x7fffffff), X(0x003243f5), X(0x7ffff621),
X(0x006487e3), X(0x7fffd886), X(0x0096cbc1), X(0x7fffa72c),
X(0x00c90f88), X(0x7fff6216), X(0x00fb5330), X(0x7fff0943),
@@ -279,7 +279,7 @@ static const LOOKUP_T sincos_lookup0[1026] = {
};
/* {sin((2*i+1)*PI/4096), cos((2*i+1)*PI/4096)}, with i = 0 to 511 */
-static const LOOKUP_T sincos_lookup1[1024] = {
+static LOOKUP_T sincos_lookup1[1024] = {
X(0x001921fb), X(0x7ffffd88), X(0x004b65ee), X(0x7fffe9cb),
X(0x007da9d4), X(0x7fffc251), X(0x00afeda8), X(0x7fff8719),
X(0x00e23160), X(0x7fff3824), X(0x011474f6), X(0x7ffed572),
diff --git a/lib/tremor/misc.c b/lib/tremor/misc.c
new file mode 100644
index 00000000..8833e13c
--- /dev/null
+++ b/lib/tremor/misc.c
@@ -0,0 +1,208 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE TremorOggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE TremorOggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * by the XIPHOPHORUS Company http://www.xiph.org/ *
+ * *
+ ********************************************************************/
+
+#define HEAD_ALIGN 64
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#define MISC_C
+#include "misc.h"
+#include <sys/time.h>
+
+static void **pointers=NULL;
+static long *insertlist=NULL; /* We can't embed this in the pointer list;
+ a pointer can have any value... */
+
+static char **files=NULL;
+static long *file_bytes=NULL;
+static int filecount=0;
+
+static int ptop=0;
+static int palloced=0;
+static int pinsert=0;
+
+typedef struct {
+ char *file;
+ long line;
+ long ptr;
+ long bytes;
+} head;
+
+long global_bytes=0;
+long start_time=-1;
+
+static void *_insert(void *ptr,long bytes,char *file,long line){
+ ((head *)ptr)->file=file;
+ ((head *)ptr)->line=line;
+ ((head *)ptr)->ptr=pinsert;
+ ((head *)ptr)->bytes=bytes-HEAD_ALIGN;
+
+ if(pinsert>=palloced){
+ palloced+=64;
+ if(pointers){
+ pointers=(void **)realloc(pointers,sizeof(void **)*palloced);
+ insertlist=(long *)realloc(insertlist,sizeof(long *)*palloced);
+ }else{
+ pointers=(void **)malloc(sizeof(void **)*palloced);
+ insertlist=(long *)malloc(sizeof(long *)*palloced);
+ }
+ }
+
+ pointers[pinsert]=ptr;
+
+ if(pinsert==ptop)
+ pinsert=++ptop;
+ else
+ pinsert=insertlist[pinsert];
+
+#ifdef _VDBG_GRAPHFILE
+ {
+ FILE *out;
+ struct timeval tv;
+ static struct timezone tz;
+ int i;
+ char buffer[80];
+ gettimeofday(&tv,&tz);
+
+ for(i=0;i<filecount;i++)
+ if(!strcmp(file,files[i]))break;
+
+ if(i==filecount){
+ filecount++;
+ if(!files){
+ files=malloc(filecount*sizeof(*files));
+ file_bytes=malloc(filecount*sizeof(*file_bytes));
+ }else{
+ files=realloc(files,filecount*sizeof(*files));
+ file_bytes=realloc(file_bytes,filecount*sizeof(*file_bytes));
+ }
+ files[i]=strdup(file);
+ file_bytes[i]=0;
+ }
+
+ file_bytes[i]+=bytes-HEAD_ALIGN;
+
+ if(start_time==-1)start_time=(tv.tv_sec*1000)+(tv.tv_usec/1000);
+
+ snprintf(buffer,80,"%s",file);
+ if(strchr(buffer,'.'))strchr(buffer,'.')[0]=0;
+ strcat(buffer,_VDBG_GRAPHFILE);
+ out=fopen(buffer,"a");
+ fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
+ file_bytes[i]-(bytes-HEAD_ALIGN));
+ fprintf(out,"%ld, %ld # FILE %s LINE %ld\n",
+ -start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
+ file_bytes[i],file,line);
+ fclose(out);
+
+ out=fopen("total"_VDBG_GRAPHFILE,"a");
+ fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
+ global_bytes);
+ fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
+ global_bytes+(bytes-HEAD_ALIGN));
+ fclose(out);
+ }
+#endif
+
+ global_bytes+=(bytes-HEAD_ALIGN);
+
+ return(ptr+HEAD_ALIGN);
+}
+
+static void _ripremove(void *ptr){
+ int insert;
+
+#ifdef _VDBG_GRAPHFILE
+ {
+ FILE *out=fopen("total"_VDBG_GRAPHFILE,"a");
+ struct timeval tv;
+ static struct timezone tz;
+ char buffer[80];
+ char *file =((head *)ptr)->file;
+ long bytes =((head *)ptr)->bytes;
+ int i;
+
+ gettimeofday(&tv,&tz);
+ fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
+ global_bytes);
+ fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
+ global_bytes-((head *)ptr)->bytes);
+ fclose(out);
+
+ for(i=0;i<filecount;i++)
+ if(!strcmp(file,files[i]))break;
+
+ snprintf(buffer,80,"%s",file);
+ if(strchr(buffer,'.'))strchr(buffer,'.')[0]=0;
+ strcat(buffer,_VDBG_GRAPHFILE);
+ out=fopen(buffer,"a");
+ fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
+ file_bytes[i]);
+ fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000),
+ file_bytes[i]-bytes);
+ fclose(out);
+
+ file_bytes[i]-=bytes;
+
+ }
+#endif
+
+ global_bytes-=((head *)ptr)->bytes;
+
+ insert=((head *)ptr)->ptr;
+ insertlist[insert]=pinsert;
+ pinsert=insert;
+
+ if(pointers[insert]==NULL){
+ fprintf(stderr,"DEBUGGING MALLOC ERROR: freeing previously freed memory\n");
+ fprintf(stderr,"\t%s %ld\n",((head *)ptr)->file,((head *)ptr)->line);
+ }
+
+ if(global_bytes<0){
+ fprintf(stderr,"DEBUGGING MALLOC ERROR: freeing unmalloced memory\n");
+ }
+
+ pointers[insert]=NULL;
+}
+
+void _VDBG_dump(void){
+ int i;
+ for(i=0;i<ptop;i++){
+ head *ptr=pointers[i];
+ if(ptr)
+ fprintf(stderr,"unfreed bytes from %s:%ld\n",
+ ptr->file,ptr->line);
+ }
+
+}
+
+extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line){
+ bytes+=HEAD_ALIGN;
+ if(ptr){
+ ptr-=HEAD_ALIGN;
+ _ripremove(ptr);
+ ptr=realloc(ptr,bytes);
+ }else{
+ ptr=malloc(bytes);
+ memset(ptr,0,bytes);
+ }
+ return _insert(ptr,bytes,file,line);
+}
+
+extern void _VDBG_free(void *ptr,char *file,long line){
+ if(ptr){
+ ptr-=HEAD_ALIGN;
+ _ripremove(ptr);
+ free(ptr);
+ }
+}
+
diff --git a/lib/tremor/misc.h b/lib/tremor/misc.h
index 1ae4d2e8..d818e183 100644
--- a/lib/tremor/misc.h
+++ b/lib/tremor/misc.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -18,18 +18,27 @@
#ifndef _V_RANDOM_H_
#define _V_RANDOM_H_
#include "ivorbiscodec.h"
-#include "os.h"
+#include "os_types.h"
-#ifdef _LOW_ACCURACY_
-# define X(n) (((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9))
-# define LOOKUP_T const unsigned char
-#else
-# define X(n) (n)
-# define LOOKUP_T const ogg_int32_t
+/*#define _VDBG_GRAPHFILE "_0.m"*/
+
+
+#ifdef _VDBG_GRAPHFILE
+extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line);
+extern void _VDBG_free(void *ptr,char *file,long line);
+
+#undef _tremor_ogg_malloc
+#undef _tremor_ogg_calloc
+#undef _tremor_ogg_realloc
+#undef _tremor_ogg_free
+
+#define _tremor_ogg_malloc(x) _VDBG_malloc(NULL,(x),__FILE__,__LINE__)
+#define _tremor_ogg_calloc(x,y) _VDBG_malloc(NULL,(x)*(y),__FILE__,__LINE__)
+#define _tremor_ogg_realloc(x,y) _VDBG_malloc((x),(y),__FILE__,__LINE__)
+#define _tremor_ogg_free(x) _VDBG_free((x),__FILE__,__LINE__)
#endif
#include "asm_arm.h"
-#include <stdlib.h> /* for abs() */
#ifndef _V_WIDE_MATH
#define _V_WIDE_MATH
@@ -37,44 +46,42 @@
#ifndef _LOW_ACCURACY_
/* 64 bit multiply */
-#if !(defined WIN32 && defined WINCE)
#include <sys/types.h>
-#endif
#if BYTE_ORDER==LITTLE_ENDIAN
union magic {
struct {
- ogg_int32_t lo;
- ogg_int32_t hi;
+ tremor_ogg_int32_t lo;
+ tremor_ogg_int32_t hi;
} halves;
- ogg_int64_t whole;
+ tremor_ogg_int64_t whole;
};
#endif
#if BYTE_ORDER==BIG_ENDIAN
union magic {
struct {
- ogg_int32_t hi;
- ogg_int32_t lo;
+ tremor_ogg_int32_t hi;
+ tremor_ogg_int32_t lo;
} halves;
- ogg_int64_t whole;
+ tremor_ogg_int64_t whole;
};
#endif
-STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
+static inline tremor_ogg_int32_t MULT32(tremor_ogg_int32_t x, tremor_ogg_int32_t y) {
union magic magic;
- magic.whole = (ogg_int64_t)x * y;
+ magic.whole = (tremor_ogg_int64_t)x * y;
return magic.halves.hi;
}
-STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
+static inline tremor_ogg_int32_t MULT31(tremor_ogg_int32_t x, tremor_ogg_int32_t y) {
return MULT32(x,y)<<1;
}
-STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
+static inline tremor_ogg_int32_t MULT31_SHIFT15(tremor_ogg_int32_t x, tremor_ogg_int32_t y) {
union magic magic;
- magic.whole = (ogg_int64_t)x * y;
- return ((ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17);
+ magic.whole = (tremor_ogg_int64_t)x * y;
+ return ((tremor_ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17);
}
#else
@@ -93,15 +100,15 @@ STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
* tables in this case.
*/
-STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
+static inline tremor_ogg_int32_t MULT32(tremor_ogg_int32_t x, tremor_ogg_int32_t y) {
return (x >> 9) * y; /* y preshifted >>23 */
}
-STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
+static inline tremor_ogg_int32_t MULT31(tremor_ogg_int32_t x, tremor_ogg_int32_t y) {
return (x >> 8) * y; /* y preshifted >>23 */
}
-STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
+static inline tremor_ogg_int32_t MULT31_SHIFT15(tremor_ogg_int32_t x, tremor_ogg_int32_t y) {
return (x >> 6) * y; /* y preshifted >>9 */
}
@@ -138,25 +145,25 @@ STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
#else
-STIN void XPROD32(ogg_int32_t a, ogg_int32_t b,
- ogg_int32_t t, ogg_int32_t v,
- ogg_int32_t *x, ogg_int32_t *y)
+static inline void XPROD32(tremor_ogg_int32_t a, tremor_ogg_int32_t b,
+ tremor_ogg_int32_t t, tremor_ogg_int32_t v,
+ tremor_ogg_int32_t *x, tremor_ogg_int32_t *y)
{
*x = MULT32(a, t) + MULT32(b, v);
*y = MULT32(b, t) - MULT32(a, v);
}
-STIN void XPROD31(ogg_int32_t a, ogg_int32_t b,
- ogg_int32_t t, ogg_int32_t v,
- ogg_int32_t *x, ogg_int32_t *y)
+static inline void XPROD31(tremor_ogg_int32_t a, tremor_ogg_int32_t b,
+ tremor_ogg_int32_t t, tremor_ogg_int32_t v,
+ tremor_ogg_int32_t *x, tremor_ogg_int32_t *y)
{
*x = MULT31(a, t) + MULT31(b, v);
*y = MULT31(b, t) - MULT31(a, v);
}
-STIN void XNPROD31(ogg_int32_t a, ogg_int32_t b,
- ogg_int32_t t, ogg_int32_t v,
- ogg_int32_t *x, ogg_int32_t *y)
+static inline void XNPROD31(tremor_ogg_int32_t a, tremor_ogg_int32_t b,
+ tremor_ogg_int32_t t, tremor_ogg_int32_t v,
+ tremor_ogg_int32_t *x, tremor_ogg_int32_t *y)
{
*x = MULT31(a, t) - MULT31(b, v);
*y = MULT31(b, t) + MULT31(a, v);
@@ -169,7 +176,7 @@ STIN void XNPROD31(ogg_int32_t a, ogg_int32_t b,
#ifndef _V_CLIP_MATH
#define _V_CLIP_MATH
-STIN ogg_int32_t CLIP_TO_15(ogg_int32_t x) {
+static inline tremor_ogg_int32_t CLIP_TO_15(tremor_ogg_int32_t x) {
int ret=x;
ret-= ((x<=32767)-1)&(x-32767);
ret-= ((x>=-32768)-1)&(x+32768);
@@ -178,73 +185,6 @@ STIN ogg_int32_t CLIP_TO_15(ogg_int32_t x) {
#endif
-STIN ogg_int32_t VFLOAT_MULT(ogg_int32_t a,ogg_int32_t ap,
- ogg_int32_t b,ogg_int32_t bp,
- ogg_int32_t *p){
- if(a && b){
-#ifndef _LOW_ACCURACY_
- *p=ap+bp+32;
- return MULT32(a,b);
-#else
- *p=ap+bp+31;
- return (a>>15)*(b>>16);
-#endif
- }else
- return 0;
-}
-
-int _ilog(unsigned int);
-
-STIN ogg_int32_t VFLOAT_MULTI(ogg_int32_t a,ogg_int32_t ap,
- ogg_int32_t i,
- ogg_int32_t *p){
-
- int ip=_ilog(abs(i))-31;
- return VFLOAT_MULT(a,ap,i<<-ip,ip,p);
-}
-
-STIN ogg_int32_t VFLOAT_ADD(ogg_int32_t a,ogg_int32_t ap,
- ogg_int32_t b,ogg_int32_t bp,
- ogg_int32_t *p){
-
- if(!a){
- *p=bp;
- return b;
- }else if(!b){
- *p=ap;
- return a;
- }
-
- /* yes, this can leak a bit. */
- if(ap>bp){
- int shift=ap-bp+1;
- *p=ap+1;
- a>>=1;
- if(shift<32){
- b=(b+(1<<(shift-1)))>>shift;
- }else{
- b=0;
- }
- }else{
- int shift=bp-ap+1;
- *p=bp+1;
- b>>=1;
- if(shift<32){
- a=(a+(1<<(shift-1)))>>shift;
- }else{
- a=0;
- }
- }
-
- a+=b;
- if((a&0xc0000000)==0xc0000000 ||
- (a&0xc0000000)==0){
- a<<=1;
- (*p)--;
- }
- return(a);
-}
-
#endif
diff --git a/lib/tremor/os.h b/lib/tremor/os.h
index 130d27de..5a556fd9 100644
--- a/lib/tremor/os.h
+++ b/lib/tremor/os.h
@@ -2,13 +2,13 @@
#define _OS_H
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -18,7 +18,7 @@
********************************************************************/
#include <math.h>
-#include <ogg/os_types.h>
+#include "os_types.h"
#ifndef _V_IFDEFJAIL_H_
# define _V_IFDEFJAIL_H_
@@ -41,8 +41,6 @@
# define rint(x) (floor((x)+0.5f))
# define NO_FLOAT_MATH_LIB
# define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b))
-# define LITTLE_ENDIAN 1
-# define BYTE_ORDER LITTLE_ENDIAN
#endif
#ifdef HAVE_ALLOCA_H
diff --git a/lib/tremor/os_types.h b/lib/tremor/os_types.h
new file mode 100644
index 00000000..c09c993d
--- /dev/null
+++ b/lib/tremor/os_types.h
@@ -0,0 +1,42 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: #ifdef jail to whip a few platforms into the UNIX ideal.
+
+ ********************************************************************/
+#ifndef _TREMOR_OS_TYPES_H
+#define _TREMOR_OS_TYPES_H
+
+#include <stdint.h>
+#ifdef _LOW_ACCURACY_
+# define X(n) (((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9))
+# define LOOKUP_T const unsigned char
+#else
+# define X(n) (n)
+# define LOOKUP_T const tremor_ogg_int32_t
+#endif
+
+/* make it easy on the folks that want to compile the libs with a
+ different malloc than stdlib */
+#define _tremor_ogg_malloc malloc
+#define _tremor_ogg_calloc calloc
+#define _tremor_ogg_realloc realloc
+#define _tremor_ogg_free free
+
+typedef int64_t tremor_ogg_int64_t;
+typedef int32_t tremor_ogg_int32_t;
+typedef uint32_t tremor_ogg_uint32_t;
+typedef int16_t tremor_ogg_int16_t;
+typedef uint16_t tremor_ogg_uint16_t;
+
+#endif /* _TREMOR_OS_TYPES_H */
diff --git a/lib/tremor/registry.c b/lib/tremor/registry.c
deleted file mode 100644
index c0b5fec0..00000000
--- a/lib/tremor/registry.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
- * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: registry for floor, res backends and channel mappings
-
- ********************************************************************/
-
-#include "ivorbiscodec.h"
-#include "codec_internal.h"
-#include "registry.h"
-#include "misc.h"
-
-
-/* seems like major overkill now; the backend numbers will grow into
- the infrastructure soon enough */
-
-extern vorbis_func_floor floor0_exportbundle;
-extern vorbis_func_floor floor1_exportbundle;
-extern vorbis_func_residue residue0_exportbundle;
-extern vorbis_func_residue residue1_exportbundle;
-extern vorbis_func_residue residue2_exportbundle;
-extern vorbis_func_mapping mapping0_exportbundle;
-
-vorbis_func_floor *_floor_P[]={
- &floor0_exportbundle,
- &floor1_exportbundle,
-};
-
-vorbis_func_residue *_residue_P[]={
- &residue0_exportbundle,
- &residue1_exportbundle,
- &residue2_exportbundle,
-};
-
-vorbis_func_mapping *_mapping_P[]={
- &mapping0_exportbundle,
-};
-
-
-
diff --git a/lib/tremor/registry.h b/lib/tremor/registry.h
deleted file mode 100644
index 2bc8068f..00000000
--- a/lib/tremor/registry.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
- * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: registry for time, floor, res backends and channel mappings
-
- ********************************************************************/
-
-#ifndef _V_REG_H_
-#define _V_REG_H_
-
-#define VI_TRANSFORMB 1
-#define VI_WINDOWB 1
-#define VI_TIMEB 1
-#define VI_FLOORB 2
-#define VI_RESB 3
-#define VI_MAPB 1
-
-#include "backends.h"
-
-#if defined(_WIN32) && defined(VORBISDLL_IMPORT)
-# define EXTERN __declspec(dllimport) extern
-#else
-# define EXTERN extern
-#endif
-
-EXTERN vorbis_func_floor *_floor_P[];
-EXTERN vorbis_func_residue *_residue_P[];
-EXTERN vorbis_func_mapping *_mapping_P[];
-
-#endif
diff --git a/lib/tremor/res012.c b/lib/tremor/res012.c
index f036caaa..e568dc10 100644
--- a/lib/tremor/res012.c
+++ b/lib/tremor/res012.c
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -18,357 +18,208 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
-#include <ogg/ogg.h>
+#include "tremor_ogg.h"
#include "ivorbiscodec.h"
#include "codec_internal.h"
-#include "registry.h"
#include "codebook.h"
#include "misc.h"
#include "os.h"
-#include "block.h"
-typedef struct {
- vorbis_info_residue0 *info;
- int map;
-
- int parts;
- int stages;
- codebook *fullbooks;
- codebook *phrasebook;
- codebook ***partbooks;
-
- int partvals;
- int **decodemap;
-
-} vorbis_look_residue0;
-
-void res0_free_info(vorbis_info_residue *i){
- vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
+void res_clear_info(vorbis_info_residue *info){
if(info){
+ if(info->stagemasks)_tremor_ogg_free(info->stagemasks);
+ if(info->stagebooks)_tremor_ogg_free(info->stagebooks);
memset(info,0,sizeof(*info));
- _ogg_free(info);
}
}
-void res0_free_look(vorbis_look_residue *i){
- int j;
- if(i){
-
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
-
- for(j=0;j<look->parts;j++)
- if(look->partbooks[j])_ogg_free(look->partbooks[j]);
- _ogg_free(look->partbooks);
- for(j=0;j<look->partvals;j++)
- _ogg_free(look->decodemap[j]);
- _ogg_free(look->decodemap);
-
- memset(look,0,sizeof(*look));
- _ogg_free(look);
- }
-}
-
-static int ilog(unsigned int v){
- int ret=0;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
-}
-
-static int icount(unsigned int v){
- int ret=0;
- while(v){
- ret+=v&1;
- v>>=1;
- }
- return(ret);
-}
/* vorbis_info is for range checking */
-vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
- int j,acc=0;
- vorbis_info_residue0 *info=(vorbis_info_residue0 *)_ogg_calloc(1,sizeof(*info));
+int res_unpack(vorbis_info_residue *info,
+ vorbis_info *vi,tremor_oggpack_buffer *opb){
+ int j,k;
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+ memset(info,0,sizeof(*info));
+
+ info->type=tremor_oggpack_read(opb,16);
+ if(info->type>2 || info->type<0)goto errout;
+ info->begin=tremor_oggpack_read(opb,24);
+ info->end=tremor_oggpack_read(opb,24);
+ info->grouping=tremor_oggpack_read(opb,24)+1;
+ info->partitions=tremor_oggpack_read(opb,6)+1;
+ info->groupbook=tremor_oggpack_read(opb,8);
+ if(info->groupbook>=ci->books)goto errout;
- 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);
-
- /* check for premature EOP */
- if(info->groupbook<0)goto errout;
+ info->stagemasks=_tremor_ogg_malloc(info->partitions*sizeof(*info->stagemasks));
+ info->stagebooks=_tremor_ogg_malloc(info->partitions*8*sizeof(*info->stagebooks));
for(j=0;j<info->partitions;j++){
- int cascade=oggpack_read(opb,3);
- int cflag=oggpack_read(opb,1);
- if(cflag<0) goto errout;
- if(cflag){
- int c=oggpack_read(opb,5);
- if(c<0) goto errout;
- cascade|=(c<<3);
- }
- info->secondstages[j]=cascade;
-
- acc+=icount(cascade);
- }
- for(j=0;j<acc;j++){
- int book=oggpack_read(opb,8);
- if(book<0) goto errout;
- info->booklist[j]=book;
+ int cascade=tremor_oggpack_read(opb,3);
+ if(tremor_oggpack_read(opb,1))
+ cascade|=(tremor_oggpack_read(opb,5)<<3);
+ info->stagemasks[j]=cascade;
}
- if(info->groupbook>=ci->books)goto errout;
- for(j=0;j<acc;j++){
- if(info->booklist[j]>=ci->books)goto errout;
- if(ci->book_param[info->booklist[j]]->maptype==0)goto errout;
- }
-
- /* verify the phrasebook is not specifying an impossible or
- inconsistent partitioning scheme. */
- /* modify the phrasebook ranging check from r16327; an early beta
- encoder had a bug where it used an oversized phrasebook by
- accident. These files should continue to be playable, but don't
- allow an exploit */
- {
- int entries = ci->book_param[info->groupbook]->entries;
- int dim = ci->book_param[info->groupbook]->dim;
- int partvals = 1;
- if (dim<1) goto errout;
- while(dim>0){
- partvals *= info->partitions;
- if(partvals > entries) goto errout;
- dim--;
+ for(j=0;j<info->partitions;j++){
+ for(k=0;k<8;k++){
+ if((info->stagemasks[j]>>k)&1){
+ unsigned char book=tremor_oggpack_read(opb,8);
+ if(book>=ci->books)goto errout;
+ info->stagebooks[j*8+k]=book;
+ if(k+1>info->stages)info->stages=k+1;
+ }else
+ info->stagebooks[j*8+k]=0xff;
}
- info->partvals = partvals;
}
- return(info);
+ if(tremor_oggpack_eop(opb))goto errout;
+
+ return 0;
errout:
- res0_free_info(info);
- return(NULL);
+ res_clear_info(info);
+ return 1;
}
-vorbis_look_residue *res0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
- vorbis_info_residue *vr){
- vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)_ogg_calloc(1,sizeof(*look));
+int res_inverse(vorbis_dsp_state *vd,vorbis_info_residue *info,
+ tremor_ogg_int32_t **in,int *nonzero,int ch){
+
+ int i,j,k,s,used=0;
codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup;
-
- int j,k,acc=0;
- int dim;
- int maxstage=0;
- look->info=info;
- look->map=vm->mapping;
-
- look->parts=info->partitions;
- look->fullbooks=ci->fullbooks;
- look->phrasebook=ci->fullbooks+info->groupbook;
- dim=look->phrasebook->dim;
-
- look->partbooks=(codebook ***)_ogg_calloc(look->parts,sizeof(*look->partbooks));
-
- for(j=0;j<look->parts;j++){
- int stages=ilog(info->secondstages[j]);
- if(stages){
- if(stages>maxstage)maxstage=stages;
- look->partbooks[j]=(codebook **)_ogg_calloc(stages,sizeof(*look->partbooks[j]));
- for(k=0;k<stages;k++)
- if(info->secondstages[j]&(1<<k)){
- look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
-#ifdef TRAIN_RES
- look->training_data[k][j]=calloc(look->partbooks[j][k]->entries,
- sizeof(***look->training_data));
-#endif
- }
- }
- }
-
- look->partvals=look->parts;
- for(j=1;j<dim;j++)look->partvals*=look->parts;
- look->stages=maxstage;
- look->decodemap=(int **)_ogg_malloc(look->partvals*sizeof(*look->decodemap));
- for(j=0;j<look->partvals;j++){
- long val=j;
- long mult=look->partvals/look->parts;
- look->decodemap[j]=(int *)_ogg_malloc(dim*sizeof(*look->decodemap[j]));
- for(k=0;k<dim;k++){
- long deco=val/mult;
- val-=deco*mult;
- mult/=look->parts;
- look->decodemap[j][k]=deco;
- }
- }
-
- return(look);
-}
-
-
-/* a truncated packet here just means 'stop working'; it's not an error */
-static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
- ogg_int32_t **in,int ch,
- long (*decodepart)(codebook *, ogg_int32_t *,
- oggpack_buffer *,int,int)){
-
- long i,j,k,l,s;
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
- vorbis_info_residue0 *info=look->info;
-
- /* move all this setup out later */
+ codebook *phrasebook=ci->book_param+info->groupbook;
int samples_per_partition=info->grouping;
- int partitions_per_word=look->phrasebook->dim;
- int max=vb->pcmend>>1;
- int end=(info->end<max?info->end:max);
- int n=end-info->begin;
+ int partitions_per_word=phrasebook->dim;
+ int pcmend=ci->blocksizes[vd->W];
- if(n>0){
- int partvals=n/samples_per_partition;
- int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
- int ***partword=(int ***)alloca(ch*sizeof(*partword));
-
- for(j=0;j<ch;j++)
- partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
+ if(info->type<2){
+ int max=pcmend>>1;
+ int end=(info->end<max?info->end:max);
+ int n=end-info->begin;
- for(s=0;s<look->stages;s++){
+ if(n>0){
+ int partvals=n/samples_per_partition;
+ int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
- /* each loop decodes on partition codeword containing
- partitions_pre_word partitions */
- for(i=0,l=0;i<partvals;l++){
- if(s==0){
- /* fetch the partition word for each channel */
- for(j=0;j<ch;j++){
- int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
- if(temp==-1 || temp>=info->partvals)goto eopbreak;
- partword[j][l]=look->decodemap[temp];
- if(partword[j][l]==NULL)goto errout;
- }
- }
+ for(i=0;i<ch;i++)
+ if(nonzero[i])
+ in[used++]=in[i];
+ ch=used;
+
+ if(used){
+
+ char **partword=(char **)alloca(ch*sizeof(*partword));
+ for(j=0;j<ch;j++)
+ partword[j]=(char *)alloca(partwords*partitions_per_word*
+ sizeof(*partword[j]));
- /* now we decode residual values for the partitions */
- for(k=0;k<partitions_per_word && i<partvals;k++,i++)
- for(j=0;j<ch;j++){
- long offset=info->begin+i*samples_per_partition;
- if(info->secondstages[partword[j][l][k]]&(1<<s)){
- codebook *stagebook=look->partbooks[partword[j][l][k]][s];
- if(stagebook){
- if(decodepart(stagebook,in[j]+offset,&vb->opb,
- samples_per_partition,-8)==-1)goto eopbreak;
+ for(s=0;s<info->stages;s++){
+
+ for(i=0;i<partvals;){
+ if(s==0){
+ /* fetch the partition word for each channel */
+
+ partword[0][i+partitions_per_word-1]=1;
+ for(k=partitions_per_word-2;k>=0;k--)
+ partword[0][i+k]=partword[0][i+k+1]*info->partitions;
+
+ for(j=1;j<ch;j++)
+ for(k=partitions_per_word-1;k>=0;k--)
+ partword[j][i+k]=partword[j-1][i+k];
+
+ for(j=0;j<ch;j++){
+ int temp=vorbis_book_decode(phrasebook,&vd->opb);
+ if(temp==-1)goto eopbreak;
+
+ /* this can be done quickly in assembly due to the quotient
+ always being at most six bits */
+ for(k=0;k<partitions_per_word;k++){
+ tremor_ogg_uint32_t div=partword[j][i+k];
+ partword[j][i+k]=temp/div;
+ temp-=partword[j][i+k]*div;
+ }
+
}
}
+
+ /* now we decode residual values for the partitions */
+ for(k=0;k<partitions_per_word && i<partvals;k++,i++)
+ for(j=0;j<ch;j++){
+ long offset=info->begin+i*samples_per_partition;
+ if(info->stagemasks[(int)partword[j][i]]&(1<<s)){
+ codebook *stagebook=ci->book_param+
+ info->stagebooks[(partword[j][i]<<3)+s];
+ if(info->type){
+ if(vorbis_book_decodev_add(stagebook,in[j]+offset,&vd->opb,
+ samples_per_partition,-8)==-1)
+ goto eopbreak;
+ }else{
+ if(vorbis_book_decodevs_add(stagebook,in[j]+offset,&vd->opb,
+ samples_per_partition,-8)==-1)
+ goto eopbreak;
+ }
+ }
+ }
}
- }
+ }
+ }
}
- }
- errout:
- eopbreak:
- return(0);
-}
-
-int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
- ogg_int32_t **in,int *nonzero,int ch){
- int i,used=0;
- for(i=0;i<ch;i++)
- if(nonzero[i])
- in[used++]=in[i];
- if(used)
- return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
- else
- return(0);
-}
-
-int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
- ogg_int32_t **in,int *nonzero,int ch){
- int i,used=0;
- for(i=0;i<ch;i++)
- if(nonzero[i])
- in[used++]=in[i];
- if(used)
- return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
- else
- return(0);
-}
-
-/* duplicate code here as speed is somewhat more important */
-int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
- ogg_int32_t **in,int *nonzero,int ch){
- long i,k,l,s;
- vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
- vorbis_info_residue0 *info=look->info;
-
- /* move all this setup out later */
- int samples_per_partition=info->grouping;
- int partitions_per_word=look->phrasebook->dim;
- int max=(vb->pcmend*ch)>>1;
- int end=(info->end<max?info->end:max);
- int n=end-info->begin;
-
- if(n>0){
+ }else{
+ int max=(pcmend*ch)>>1;
+ int end=(info->end<max?info->end:max);
+ int n=end-info->begin;
- int partvals=n/samples_per_partition;
- int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
- int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword));
- int beginoff=info->begin/ch;
-
- for(i=0;i<ch;i++)if(nonzero[i])break;
- if(i==ch)return(0); /* no nonzero vectors */
-
- samples_per_partition/=ch;
-
- for(s=0;s<look->stages;s++){
- for(i=0,l=0;i<partvals;l++){
-
- if(s==0){
- /* fetch the partition word */
- int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
- if(temp==-1 || temp>=info->partvals)goto eopbreak;
- partword[l]=look->decodemap[temp];
- if(partword[l]==NULL)goto errout;
- }
-
- /* now we decode residual values for the partitions */
- for(k=0;k<partitions_per_word && i<partvals;k++,i++)
- if(info->secondstages[partword[l][k]]&(1<<s)){
- codebook *stagebook=look->partbooks[partword[l][k]][s];
+ if(n>0){
+ int partvals=n/samples_per_partition;
+ int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
+
+ char *partword=
+ (char *)alloca(partwords*partitions_per_word*sizeof(*partword));
+ int beginoff=info->begin/ch;
+
+ for(i=0;i<ch;i++)if(nonzero[i])break;
+ if(i==ch)return(0); /* no nonzero vectors */
+
+ samples_per_partition/=ch;
+
+ for(s=0;s<info->stages;s++){
+ for(i=0;i<partvals;){
+
+ if(s==0){
+ int temp;
+ partword[i+partitions_per_word-1]=1;
+ for(k=partitions_per_word-2;k>=0;k--)
+ partword[i+k]=partword[i+k+1]*info->partitions;
- if(stagebook){
+ /* fetch the partition word */
+ temp=vorbis_book_decode(phrasebook,&vd->opb);
+ if(temp==-1)goto eopbreak;
+
+ /* this can be done quickly in assembly due to the quotient
+ always being at most six bits */
+ for(k=0;k<partitions_per_word;k++){
+ tremor_ogg_uint32_t div=partword[i+k];
+ partword[i+k]=temp/div;
+ temp-=partword[i+k]*div;
+ }
+ }
+
+ /* now we decode residual values for the partitions */
+ for(k=0;k<partitions_per_word && i<partvals;k++,i++)
+ if(info->stagemasks[(int)partword[i]]&(1<<s)){
+ codebook *stagebook=ci->book_param+
+ info->stagebooks[(partword[i]<<3)+s];
if(vorbis_book_decodevv_add(stagebook,in,
i*samples_per_partition+beginoff,ch,
- &vb->opb,
+ &vd->opb,
samples_per_partition,-8)==-1)
goto eopbreak;
}
- }
+ }
}
}
}
errout:
eopbreak:
- return(0);
-}
-
-
-vorbis_func_residue residue0_exportbundle={
- &res0_unpack,
- &res0_look,
- &res0_free_info,
- &res0_free_look,
- &res0_inverse
-};
-
-vorbis_func_residue residue1_exportbundle={
- &res0_unpack,
- &res0_look,
- &res0_free_info,
- &res0_free_look,
- &res1_inverse
-};
+
+ return 0;
+}
-vorbis_func_residue residue2_exportbundle={
- &res0_unpack,
- &res0_look,
- &res0_free_info,
- &res0_free_look,
- &res2_inverse
-};
diff --git a/lib/tremor/sharedbook.c b/lib/tremor/sharedbook.c
deleted file mode 100644
index 188485e3..00000000
--- a/lib/tremor/sharedbook.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
- * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: basic shared codebook operations
-
- ********************************************************************/
-
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <ogg/ogg.h>
-#include "misc.h"
-#include "ivorbiscodec.h"
-#include "codebook.h"
-
-/**** pack/unpack helpers ******************************************/
-int _ilog(unsigned int v){
- int ret=0;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
-}
-
-/* 32 bit float (not IEEE; nonnormalized mantissa +
- biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
- Why not IEEE? It's just not that important here. */
-
-#define VQ_FEXP 10
-#define VQ_FMAN 21
-#define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */
-
-static ogg_int32_t _float32_unpack(long val,int *point){
- long mant=val&0x1fffff;
- int sign=val&0x80000000;
- long exp =(val&0x7fe00000L)>>VQ_FMAN;
-
- exp-=(VQ_FMAN-1)+VQ_FEXP_BIAS;
-
- if(mant){
- while(!(mant&0x40000000)){
- mant<<=1;
- exp-=1;
- }
-
- if(sign)mant= -mant;
- }else{
- sign=0;
- exp=-9999;
- }
-
- *point=exp;
- return mant;
-}
-
-/* given a list of word lengths, generate a list of codewords. Works
- for length ordered or unordered, always assigns the lowest valued
- codewords first. Extended to handle unused entries (length 0) */
-ogg_uint32_t *_make_words(long *l,long n,long sparsecount){
- long i,j,count=0;
- ogg_uint32_t marker[33];
- ogg_uint32_t *r=(ogg_uint32_t *)_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r));
- memset(marker,0,sizeof(marker));
-
- for(i=0;i<n;i++){
- long length=l[i];
- if(length>0){
- ogg_uint32_t entry=marker[length];
-
- /* when we claim a node for an entry, we also claim the nodes
- below it (pruning off the imagined tree that may have dangled
- from it) as well as blocking the use of any nodes directly
- above for leaves */
-
- /* update ourself */
- if(length<32 && (entry>>length)){
- /* error condition; the lengths must specify an overpopulated tree */
- _ogg_free(r);
- return(NULL);
- }
- r[count++]=entry;
-
- /* Look to see if the next shorter marker points to the node
- above. if so, update it and repeat. */
- {
- for(j=length;j>0;j--){
-
- if(marker[j]&1){
- /* have to jump branches */
- if(j==1)
- marker[1]++;
- else
- marker[j]=marker[j-1]<<1;
- break; /* invariant says next upper marker would already
- have been moved if it was on the same path */
- }
- marker[j]++;
- }
- }
-
- /* prune the tree; the implicit invariant says all the longer
- markers were dangling from our just-taken node. Dangle them
- from our *new* node. */
- for(j=length+1;j<33;j++)
- if((marker[j]>>1) == entry){
- entry=marker[j];
- marker[j]=marker[j-1]<<1;
- }else
- break;
- }else
- if(sparsecount==0)count++;
- }
-
- /* sanity check the huffman tree; an underpopulated tree must be
- rejected. The only exception is the one-node pseudo-nil tree,
- which appears to be underpopulated because the tree doesn't
- really exist; there's only one possible 'codeword' or zero bits,
- but the above tree-gen code doesn't mark that. */
- if(sparsecount != 1){
- for(i=1;i<33;i++)
- if(marker[i] & (0xffffffffUL>>(32-i))){
- _ogg_free(r);
- return(NULL);
- }
- }
-
- /* bitreverse the words because our bitwise packer/unpacker is LSb
- endian */
- for(i=0,count=0;i<n;i++){
- ogg_uint32_t temp=0;
- for(j=0;j<l[i];j++){
- temp<<=1;
- temp|=(r[count]>>j)&1;
- }
-
- if(sparsecount){
- if(l[i])
- r[count++]=temp;
- }else
- r[count++]=temp;
- }
-
- return(r);
-}
-
-/* there might be a straightforward one-line way to do the below
- that's portable and totally safe against roundoff, but I haven't
- thought of it. Therefore, we opt on the side of caution */
-long _book_maptype1_quantvals(const static_codebook *b){
- /* get us a starting hint, we'll polish it below */
- int bits=_ilog(b->entries);
- int vals=b->entries>>((bits-1)*(b->dim-1)/b->dim);
-
- while(1){
- long acc=1;
- long acc1=1;
- int i;
- for(i=0;i<b->dim;i++){
- acc*=vals;
- acc1*=vals+1;
- }
- if(acc<=b->entries && acc1>b->entries){
- return(vals);
- }else{
- if(acc>b->entries){
- vals--;
- }else{
- vals++;
- }
- }
- }
-}
-
-/* different than what _book_unquantize does for mainline:
- we repack the book in a fixed point format that shares the same
- binary point. Upon first use, we can shift point if needed */
-
-/* we need to deal with two map types: in map type 1, the values are
- generated algorithmically (each column of the vector counts through
- the values in the quant vector). in map type 2, all the values came
- in in an explicit list. Both value lists must be unpacked */
-
-ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap,
- int *maxpoint){
- long j,k,count=0;
- if(b->maptype==1 || b->maptype==2){
- int quantvals;
- int minpoint,delpoint;
- ogg_int32_t mindel=_float32_unpack(b->q_min,&minpoint);
- ogg_int32_t delta=_float32_unpack(b->q_delta,&delpoint);
- ogg_int32_t *r=(ogg_int32_t *)_ogg_calloc(n*b->dim,sizeof(*r));
- int *rp=(int *)_ogg_calloc(n*b->dim,sizeof(*rp));
-
- *maxpoint=minpoint;
-
- /* maptype 1 and 2 both use a quantized value vector, but
- different sizes */
- switch(b->maptype){
- case 1:
- /* most of the time, entries%dimensions == 0, but we need to be
- well defined. We define that the possible vales at each
- scalar is values == entries/dim. If entries%dim != 0, we'll
- have 'too few' values (values*dim<entries), which means that
- we'll have 'left over' entries; left over entries use zeroed
- values (and are wasted). So don't generate codebooks like
- that */
- quantvals=_book_maptype1_quantvals(b);
- for(j=0;j<b->entries;j++){
- if((sparsemap && b->lengthlist[j]) || !sparsemap){
- ogg_int32_t last=0;
- int lastpoint=0;
- int indexdiv=1;
- for(k=0;k<b->dim;k++){
- int index= (j/indexdiv)%quantvals;
- int point=0;
- int val=VFLOAT_MULTI(delta,delpoint,
- abs(b->quantlist[index]),&point);
-
- val=VFLOAT_ADD(mindel,minpoint,val,point,&point);
- val=VFLOAT_ADD(last,lastpoint,val,point,&point);
-
- if(b->q_sequencep){
- last=val;
- lastpoint=point;
- }
-
- if(sparsemap){
- r[sparsemap[count]*b->dim+k]=val;
- rp[sparsemap[count]*b->dim+k]=point;
- }else{
- r[count*b->dim+k]=val;
- rp[count*b->dim+k]=point;
- }
- if(*maxpoint<point)*maxpoint=point;
- indexdiv*=quantvals;
- }
- count++;
- }
-
- }
- break;
- case 2:
- for(j=0;j<b->entries;j++){
- if((sparsemap && b->lengthlist[j]) || !sparsemap){
- ogg_int32_t last=0;
- int lastpoint=0;
-
- for(k=0;k<b->dim;k++){
- int point=0;
- int val=VFLOAT_MULTI(delta,delpoint,
- abs(b->quantlist[j*b->dim+k]),&point);
-
- val=VFLOAT_ADD(mindel,minpoint,val,point,&point);
- val=VFLOAT_ADD(last,lastpoint,val,point,&point);
-
- if(b->q_sequencep){
- last=val;
- lastpoint=point;
- }
-
- if(sparsemap){
- r[sparsemap[count]*b->dim+k]=val;
- rp[sparsemap[count]*b->dim+k]=point;
- }else{
- r[count*b->dim+k]=val;
- rp[count*b->dim+k]=point;
- }
- if(*maxpoint<point)*maxpoint=point;
- }
- count++;
- }
- }
- break;
- }
-
- for(j=0;j<n*b->dim;j++)
- if(rp[j]<*maxpoint)
- r[j]>>=*maxpoint-rp[j];
-
- _ogg_free(rp);
- return(r);
- }
- return(NULL);
-}
-
-void vorbis_staticbook_destroy(static_codebook *b){
- if(b->quantlist)_ogg_free(b->quantlist);
- if(b->lengthlist)_ogg_free(b->lengthlist);
- memset(b,0,sizeof(*b));
- _ogg_free(b);
-}
-
-void vorbis_book_clear(codebook *b){
- /* static book is not cleared; we're likely called on the lookup and
- the static codebook belongs to the info struct */
- if(b->valuelist)_ogg_free(b->valuelist);
- if(b->codelist)_ogg_free(b->codelist);
-
- if(b->dec_index)_ogg_free(b->dec_index);
- if(b->dec_codelengths)_ogg_free(b->dec_codelengths);
- if(b->dec_firsttable)_ogg_free(b->dec_firsttable);
-
- memset(b,0,sizeof(*b));
-}
-
-static ogg_uint32_t bitreverse(ogg_uint32_t x){
- x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL);
- x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL);
- x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL);
- x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL);
- return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL);
-}
-
-static int sort32a(const void *a,const void *b){
- return (**(ogg_uint32_t **)a>**(ogg_uint32_t **)b)-
- (**(ogg_uint32_t **)a<**(ogg_uint32_t **)b);
-}
-
-/* decode codebook arrangement is more heavily optimized than encode */
-int vorbis_book_init_decode(codebook *c,const static_codebook *s){
- int i,j,n=0,tabn;
- int *sortindex;
- memset(c,0,sizeof(*c));
-
- /* count actually used entries */
- for(i=0;i<s->entries;i++)
- if(s->lengthlist[i]>0)
- n++;
-
- c->entries=s->entries;
- c->used_entries=n;
- c->dim=s->dim;
-
- if(n>0){
- /* two different remappings go on here.
-
- First, we collapse the likely sparse codebook down only to
- actually represented values/words. This collapsing needs to be
- indexed as map-valueless books are used to encode original entry
- positions as integers.
-
- Second, we reorder all vectors, including the entry index above,
- by sorted bitreversed codeword to allow treeless decode. */
-
- /* perform sort */
- ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries);
- ogg_uint32_t **codep=(ogg_uint32_t **)alloca(sizeof(*codep)*n);
-
- if(codes==NULL)goto err_out;
-
- for(i=0;i<n;i++){
- codes[i]=bitreverse(codes[i]);
- codep[i]=codes+i;
- }
-
- qsort(codep,n,sizeof(*codep),sort32a);
-
- sortindex=(int *)alloca(n*sizeof(*sortindex));
- c->codelist=(ogg_uint32_t *)_ogg_malloc(n*sizeof(*c->codelist));
- /* the index is a reverse index */
- for(i=0;i<n;i++){
- int position=codep[i]-codes;
- sortindex[position]=i;
- }
-
- for(i=0;i<n;i++)
- c->codelist[sortindex[i]]=codes[i];
- _ogg_free(codes);
-
-
-
- c->valuelist=_book_unquantize(s,n,sortindex,&c->binarypoint);
- c->dec_index=(int *)_ogg_malloc(n*sizeof(*c->dec_index));
-
- for(n=0,i=0;i<s->entries;i++)
- if(s->lengthlist[i]>0)
- c->dec_index[sortindex[n++]]=i;
-
- c->dec_codelengths=(char *)_ogg_malloc(n*sizeof(*c->dec_codelengths));
- for(n=0,i=0;i<s->entries;i++)
- if(s->lengthlist[i]>0)
- c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
-
- c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */
- if(c->dec_firsttablen<5)c->dec_firsttablen=5;
- if(c->dec_firsttablen>8)c->dec_firsttablen=8;
-
- tabn=1<<c->dec_firsttablen;
- c->dec_firsttable=(ogg_uint32_t *)_ogg_calloc(tabn,sizeof(*c->dec_firsttable));
- c->dec_maxlength=0;
-
- for(i=0;i<n;i++){
- if(c->dec_maxlength<c->dec_codelengths[i])
- c->dec_maxlength=c->dec_codelengths[i];
- if(c->dec_codelengths[i]<=c->dec_firsttablen){
- ogg_uint32_t orig=bitreverse(c->codelist[i]);
- for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++)
- c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1;
- }
- }
-
- /* now fill in 'unused' entries in the firsttable with hi/lo search
- hints for the non-direct-hits */
- {
- ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen);
- long lo=0,hi=0;
-
- for(i=0;i<tabn;i++){
- ogg_uint32_t word=i<<(32-c->dec_firsttablen);
- if(c->dec_firsttable[bitreverse(word)]==0){
- while((lo+1)<n && c->codelist[lo+1]<=word)lo++;
- while( hi<n && word>=(c->codelist[hi]&mask))hi++;
-
- /* we only actually have 15 bits per hint to play with here.
- In order to overflow gracefully (nothing breaks, efficiency
- just drops), encode as the difference from the extremes. */
- {
- unsigned long loval=lo;
- unsigned long hival=n-hi;
-
- if(loval>0x7fff)loval=0x7fff;
- if(hival>0x7fff)hival=0x7fff;
- c->dec_firsttable[bitreverse(word)]=
- 0x80000000UL | (loval<<15) | hival;
- }
- }
- }
- }
- }
-
- return(0);
- err_out:
- vorbis_book_clear(c);
- return(-1);
-}
-
diff --git a/lib/tremor/synthesis.c b/lib/tremor/synthesis.c
deleted file mode 100644
index d22cb823..00000000
--- a/lib/tremor/synthesis.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
- * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.4 2003/03/29 03:07:21 xiphmont Exp $
-
- ********************************************************************/
-
-#include <stdio.h>
-#include <ogg/ogg.h>
-#include "ivorbiscodec.h"
-#include "codec_internal.h"
-#include "registry.h"
-#include "misc.h"
-#include "block.h"
-
-static int _vorbis_synthesis1(vorbis_block *vb,ogg_packet *op,int decodep){
- vorbis_dsp_state *vd= vb ? vb->vd : 0;
- private_state *b= vd ? (private_state *)vd->backend_state: 0;
- vorbis_info *vi= vd ? vd->vi : 0;
- codec_setup_info *ci= vi ? (codec_setup_info *)vi->codec_setup : 0;
- oggpack_buffer *opb=vb ? &vb->opb : 0;
- int type,mode,i;
-
- if (!vd || !b || !vi || !ci || !opb) {
- return OV_EBADPACKET;
- }
-
- /* first things first. Make sure decode is ready */
- _vorbis_block_ripcord(vb);
- oggpack_readinit(opb,op->packet,op->bytes);
-
- /* Check the packet type */
- if(oggpack_read(opb,1)!=0){
- /* Oops. This is not an audio data packet */
- return(OV_ENOTAUDIO);
- }
-
- /* read our mode and pre/post windowsize */
- mode=oggpack_read(opb,b->modebits);
- if(mode==-1)return(OV_EBADPACKET);
-
- vb->mode=mode;
- if(!ci->mode_param[mode]){
- return(OV_EBADPACKET);
- }
-
- vb->W=ci->mode_param[mode]->blockflag;
- if(vb->W){
- vb->lW=oggpack_read(opb,1);
- vb->nW=oggpack_read(opb,1);
- if(vb->nW==-1) return(OV_EBADPACKET);
- }else{
- vb->lW=0;
- vb->nW=0;
- }
-
- /* more setup */
- vb->granulepos=op->granulepos;
- vb->sequence=op->packetno; /* first block is third packet */
- vb->eofflag=op->e_o_s;
-
- if(decodep){
- /* alloc pcm passback storage */
- vb->pcmend=ci->blocksizes[vb->W];
- vb->pcm=(ogg_int32_t **)_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
- for(i=0;i<vi->channels;i++)
- vb->pcm[i]=(ogg_int32_t *)_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
-
- /* unpack_header enforces range checking */
- type=ci->map_type[ci->mode_param[mode]->mapping];
-
- return(_mapping_P[type]->inverse(vb,b->mode[mode]));
- }else{
- /* no pcm */
- vb->pcmend=0;
- vb->pcm=NULL;
-
- return(0);
- }
-}
-
-int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
- return _vorbis_synthesis1(vb,op,1);
-}
-
-/* used to track pcm position without actually performing decode.
- Useful for sequential 'fast forward' */
-int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
- return _vorbis_synthesis1(vb,op,0);
-}
-
-long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
- codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
- oggpack_buffer opb;
- int mode;
-
- oggpack_readinit(&opb,op->packet,op->bytes);
-
- /* Check the packet type */
- if(oggpack_read(&opb,1)!=0){
- /* Oops. This is not an audio data packet */
- return(OV_ENOTAUDIO);
- }
-
- {
- int modebits=0;
- int v=ci->modes;
- while(v>1){
- modebits++;
- v>>=1;
- }
-
- /* read our mode and pre/post windowsize */
- mode=oggpack_read(&opb,modebits);
- }
- if(mode==-1 || !ci->mode_param[mode])return(OV_EBADPACKET);
- return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
-}
-
-
diff --git a/lib/tremor/tremor_ogg.h b/lib/tremor/tremor_ogg.h
new file mode 100644
index 00000000..758573c7
--- /dev/null
+++ b/lib/tremor/tremor_ogg.h
@@ -0,0 +1,206 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: subsumed libogg includes
+
+ ********************************************************************/
+#ifndef _TREMOR_OGG_H
+#define _TREMOR_OGG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "os_types.h"
+
+typedef struct tremor_ogg_buffer_state{
+ struct tremor_ogg_buffer *unused_buffers;
+ struct tremor_ogg_reference *unused_references;
+ int outstanding;
+ int shutdown;
+} tremor_ogg_buffer_state;
+
+typedef struct tremor_ogg_buffer {
+ unsigned char *data;
+ long size;
+ int refcount;
+
+ union {
+ tremor_ogg_buffer_state *owner;
+ struct tremor_ogg_buffer *next;
+ } ptr;
+} tremor_ogg_buffer;
+
+typedef struct tremor_ogg_reference {
+ tremor_ogg_buffer *buffer;
+ long begin;
+ long length;
+
+ struct tremor_ogg_reference *next;
+} tremor_ogg_reference;
+
+typedef struct tremor_oggpack_buffer {
+ int headbit;
+ unsigned char *headptr;
+ long headend;
+
+ /* memory management */
+ tremor_ogg_reference *head;
+ tremor_ogg_reference *tail;
+
+ /* render the byte/bit counter API constant time */
+ long count; /* doesn't count the tail */
+} tremor_oggpack_buffer;
+
+typedef struct oggbyte_buffer {
+ tremor_ogg_reference *baseref;
+
+ tremor_ogg_reference *ref;
+ unsigned char *ptr;
+ long pos;
+ long end;
+} oggbyte_buffer;
+
+typedef struct tremor_ogg_sync_state {
+ /* decode memory management pool */
+ tremor_ogg_buffer_state *bufferpool;
+
+ /* stream buffers */
+ tremor_ogg_reference *fifo_head;
+ tremor_ogg_reference *fifo_tail;
+ long fifo_fill;
+
+ /* stream sync management */
+ int unsynced;
+ int headerbytes;
+ int bodybytes;
+
+} tremor_ogg_sync_state;
+
+typedef struct tremor_ogg_stream_state {
+ tremor_ogg_reference *header_head;
+ tremor_ogg_reference *header_tail;
+ tremor_ogg_reference *body_head;
+ tremor_ogg_reference *body_tail;
+
+ 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;
+ long pageno;
+ tremor_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 */
+ tremor_ogg_int64_t granulepos;
+
+ int lacing_fill;
+ tremor_ogg_uint32_t body_fill;
+
+ /* decode-side state data */
+ int holeflag;
+ int spanflag;
+ int clearflag;
+ int laceptr;
+ tremor_ogg_uint32_t body_fill_next;
+
+} tremor_ogg_stream_state;
+
+typedef struct {
+ tremor_ogg_reference *packet;
+ long bytes;
+ long b_o_s;
+ long e_o_s;
+ tremor_ogg_int64_t granulepos;
+ tremor_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 */
+} tremor_ogg_packet;
+
+typedef struct {
+ tremor_ogg_reference *header;
+ int header_len;
+ tremor_ogg_reference *body;
+ long body_len;
+} tremor_ogg_page;
+
+/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
+
+extern void tremor_oggpack_readinit(tremor_oggpack_buffer *b,tremor_ogg_reference *r);
+extern long tremor_oggpack_look(tremor_oggpack_buffer *b,int bits);
+extern void tremor_oggpack_adv(tremor_oggpack_buffer *b,int bits);
+extern long tremor_oggpack_read(tremor_oggpack_buffer *b,int bits);
+extern long tremor_oggpack_bytes(tremor_oggpack_buffer *b);
+extern long tremor_oggpack_bits(tremor_oggpack_buffer *b);
+extern int tremor_oggpack_eop(tremor_oggpack_buffer *b);
+
+/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
+
+extern tremor_ogg_sync_state *tremor_ogg_sync_create(void);
+extern int tremor_ogg_sync_destroy(tremor_ogg_sync_state *oy);
+extern int tremor_ogg_sync_reset(tremor_ogg_sync_state *oy);
+
+extern unsigned char *tremor_ogg_sync_bufferin(tremor_ogg_sync_state *oy, long size);
+extern int tremor_ogg_sync_wrote(tremor_ogg_sync_state *oy, long bytes);
+extern long tremor_ogg_sync_pageseek(tremor_ogg_sync_state *oy,tremor_ogg_page *og);
+extern int tremor_ogg_sync_pageout(tremor_ogg_sync_state *oy, tremor_ogg_page *og);
+extern int tremor_ogg_stream_pagein(tremor_ogg_stream_state *os, tremor_ogg_page *og);
+extern int tremor_ogg_stream_packetout(tremor_ogg_stream_state *os,tremor_ogg_packet *op);
+extern int tremor_ogg_stream_packetpeek(tremor_ogg_stream_state *os,tremor_ogg_packet *op);
+
+/* Ogg BITSTREAM PRIMITIVES: general ***************************/
+
+extern tremor_ogg_stream_state *tremor_ogg_stream_create(int serialno);
+extern int tremor_ogg_stream_destroy(tremor_ogg_stream_state *os);
+extern int tremor_ogg_stream_reset(tremor_ogg_stream_state *os);
+extern int tremor_ogg_stream_reset_serialno(tremor_ogg_stream_state *os,int serialno);
+extern int tremor_ogg_stream_eos(tremor_ogg_stream_state *os);
+
+extern int tremor_ogg_page_checksum_set(tremor_ogg_page *og);
+
+extern int tremor_ogg_page_version(tremor_ogg_page *og);
+extern int tremor_ogg_page_continued(tremor_ogg_page *og);
+extern int tremor_ogg_page_bos(tremor_ogg_page *og);
+extern int tremor_ogg_page_eos(tremor_ogg_page *og);
+extern tremor_ogg_int64_t tremor_ogg_page_granulepos(tremor_ogg_page *og);
+extern tremor_ogg_uint32_t tremor_ogg_page_serialno(tremor_ogg_page *og);
+extern tremor_ogg_uint32_t tremor_ogg_page_pageno(tremor_ogg_page *og);
+extern int tremor_ogg_page_packets(tremor_ogg_page *og);
+extern int tremor_ogg_page_getbuffer(tremor_ogg_page *og, unsigned char **buffer);
+
+extern int tremor_ogg_packet_release(tremor_ogg_packet *op);
+extern int tremor_ogg_page_release(tremor_ogg_page *og);
+
+extern void tremor_ogg_page_dup(tremor_ogg_page *d, tremor_ogg_page *s);
+
+/* Ogg BITSTREAM PRIMITIVES: return codes ***************************/
+
+#define OGG_SUCCESS 0
+
+#define OGG_HOLE -10
+#define OGG_SPAN -11
+#define OGG_EVERSION -12
+#define OGG_ESERIAL -13
+#define OGG_EINVAL -14
+#define OGG_EEOS -15
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TREMOR_OGG_H */
diff --git a/lib/tremor/vorbisfile.c b/lib/tremor/vorbisfile.c
index cd4814df..79cdefcd 100644
--- a/lib/tremor/vorbisfile.c
+++ b/lib/tremor/vorbisfile.c
@@ -1,18 +1,18 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2014 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id$
+ last mod: $Id: vorbisfile.c,v 1.6.2.5 2003/11/20 06:16:17 xiphmont Exp $
********************************************************************/
@@ -22,12 +22,19 @@
#include <string.h>
#include <math.h>
-#include "ivorbiscodec.h"
+#include "codec_internal.h"
#include "ivorbisfile.h"
#include "os.h"
#include "misc.h"
+#define NOTOPEN 0
+#define PARTOPEN 1
+#define OPENED 2
+#define STREAMSET 3 /* serialno and link set, but not to current link */
+#define LINKSET 4 /* serialno and link set to current link */
+#define INITSET 5
+
/* A 'chained bitstream' is a Vorbis bitstream that contains more than
one logical bitstream arranged end to end (the only form of Ogg
multiplexing allowed in a Vorbis bitstream; grouping [parallel
@@ -52,42 +59,35 @@
we only want coarse navigation through the stream. */
/*************************************************************************
- * Many, many internal helpers. The intention is not to be confusing;
- * rampant duplication and monolithic function implementation would be
+ * Many, many internal helpers. The intention is not to be confusing;
+ * rampant duplication and monolithic function implementation would be
* harder to understand anyway. The high level functions are last. Begin
* grokking near the end of the file */
-/* read a little more data from the file/pipe into the ogg_sync framer */
-static long _get_data(OggVorbis_File *vf){
+/* read a little more data from the file/pipe into the tremor_ogg_sync framer */
+static long _get_data(TremorOggVorbis_File *vf){
errno=0;
- if(!(vf->callbacks.read_func))return(-1);
if(vf->datasource){
- char *buffer=ogg_sync_buffer(&vf->oy,READSIZE);
- long bytes=(vf->callbacks.read_func)(buffer,1,READSIZE,vf->datasource);
- if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
- if(bytes==0 && errno)return(-1);
- return(bytes);
+ unsigned char *buffer=tremor_ogg_sync_bufferin(vf->oy,CHUNKSIZE);
+ long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
+ if(bytes>0)tremor_ogg_sync_wrote(vf->oy,bytes);
+ if(bytes==0 && errno)return -1;
+ return bytes;
}else
- return(0);
+ return 0;
}
/* save a tiny smidge of verbosity to make the code more readable */
-static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
- if(vf->datasource){
- /* only seek if the file position isn't already there */
- if(vf->offset != offset){
- if(!(vf->callbacks.seek_func)||
- (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
- return OV_EREAD;
- vf->offset=offset;
- ogg_sync_reset(&vf->oy);
- }
+static void _seek_helper(TremorOggVorbis_File *vf,tremor_ogg_int64_t offset){
+ if(vf->datasource){
+ (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
+ vf->offset=offset;
+ tremor_ogg_sync_reset(vf->oy);
}else{
/* shouldn't happen unless someone writes a broken callback */
- return OV_EFAULT;
+ return;
}
- return 0;
}
/* The read/seek functions track absolute position within the stream */
@@ -98,310 +98,221 @@ static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
boundary: -1) unbounded search
0) read no additional data; use cached only
- n) search for a new page beginning for n bytes
+ n) search for a new page beginning for n bytes
return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
- n) found a page at absolute offset n */
+ n) found a page at absolute offset n
+
+ produces a refcounted page */
-static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
- ogg_int64_t boundary){
+static tremor_ogg_int64_t _get_next_page(TremorOggVorbis_File *vf,tremor_ogg_page *og,
+ tremor_ogg_int64_t boundary){
if(boundary>0)boundary+=vf->offset;
while(1){
long more;
- if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
- more=ogg_sync_pageseek(&vf->oy,og);
-
+ if(boundary>0 && vf->offset>=boundary)return OV_FALSE;
+ more=tremor_ogg_sync_pageseek(vf->oy,og);
+
if(more<0){
/* skipped n bytes */
vf->offset-=more;
}else{
if(more==0){
- /* send more paramedics */
- if(!boundary)return(OV_FALSE);
- {
- long ret=_get_data(vf);
- if(ret==0)return(OV_EOF);
- if(ret<0)return(OV_EREAD);
- }
+ /* send more paramedics */
+ if(!boundary)return OV_FALSE;
+ {
+ long ret=_get_data(vf);
+ if(ret==0)return OV_EOF;
+ if(ret<0)return OV_EREAD;
+ }
}else{
- /* got a page. Return the offset at the page beginning,
+ /* got a page. Return the offset at the page beginning,
advance the internal offset past the page end */
- ogg_int64_t ret=vf->offset;
- vf->offset+=more;
- return(ret);
-
+ tremor_ogg_int64_t ret=vf->offset;
+ vf->offset+=more;
+ return ret;
+
}
}
}
}
-/* find the latest page beginning before the passed in position. Much
- dirtier than the above as Ogg doesn't have any backward search
- linkage. no 'readp' as it will certainly have to read. */
-/* returns offset or OV_EREAD, OV_FAULT */
-static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_int64_t begin,ogg_page *og){
- ogg_int64_t end = begin;
- ogg_int64_t ret;
- ogg_int64_t offset=-1;
+/* find the latest page beginning before the current stream cursor
+ position. Much dirtier than the above as Ogg doesn't have any
+ backward search linkage. no 'readp' as it will certainly have to
+ read. */
+/* returns offset or OV_EREAD, OV_FAULT and produces a refcounted page */
+
+static tremor_ogg_int64_t _get_prev_page(TremorOggVorbis_File *vf,tremor_ogg_page *og){
+ tremor_ogg_int64_t begin=vf->offset;
+ tremor_ogg_int64_t end=begin;
+ tremor_ogg_int64_t ret;
+ tremor_ogg_int64_t offset=-1;
while(offset==-1){
begin-=CHUNKSIZE;
if(begin<0)
begin=0;
-
- ret=_seek_helper(vf,begin);
- if(ret)return(ret);
-
+ _seek_helper(vf,begin);
while(vf->offset<end){
- memset(og,0,sizeof(*og));
ret=_get_next_page(vf,og,end-vf->offset);
- if(ret==OV_EREAD)return(OV_EREAD);
+ if(ret==OV_EREAD)return OV_EREAD;
if(ret<0){
- break;
+ break;
}else{
- offset=ret;
+ offset=ret;
}
}
}
- /* In a fully compliant, non-multiplexed stream, we'll still be
- holding the last page. In multiplexed (or noncompliant streams),
- we will probably have to re-read the last page we saw */
- if(og->header_len==0){
- ret=_seek_helper(vf,offset);
- if(ret)return(ret);
-
- ret=_get_next_page(vf,og,CHUNKSIZE);
- if(ret<0)
- /* this shouldn't be possible */
- return(OV_EFAULT);
- }
+ /* we have the offset. Actually snork and hold the page now */
+ _seek_helper(vf,offset);
+ ret=_get_next_page(vf,og,CHUNKSIZE);
+ if(ret<0)
+ /* this shouldn't be possible */
+ return OV_EFAULT;
- return(offset);
+ return offset;
}
-static void _add_serialno(ogg_page *og,ogg_uint32_t **serialno_list, int *n){
- ogg_uint32_t s = ogg_page_serialno(og);
- (*n)++;
-
- if(*serialno_list){
- *serialno_list = _ogg_realloc(*serialno_list, sizeof(**serialno_list)*(*n));
- }else{
- *serialno_list = _ogg_malloc(sizeof(**serialno_list));
+/* finds each bitstream link one at a time using a bisection search
+ (has to begin by knowing the offset of the lb's initial page).
+ Recurses for each link so it can alloc the link storage after
+ finding them all, then unroll and fill the cache at the same time */
+static int _bisect_forward_serialno(TremorOggVorbis_File *vf,
+ tremor_ogg_int64_t begin,
+ tremor_ogg_int64_t searched,
+ tremor_ogg_int64_t end,
+ tremor_ogg_uint32_t currentno,
+ long m){
+ tremor_ogg_int64_t endsearched=end;
+ tremor_ogg_int64_t next=end;
+ tremor_ogg_page og={0,0,0,0};
+ tremor_ogg_int64_t ret;
+
+ /* the below guards against garbage seperating the last and
+ first pages of two links. */
+ while(searched<endsearched){
+ tremor_ogg_int64_t bisect;
+
+ if(endsearched-searched<CHUNKSIZE){
+ bisect=searched;
+ }else{
+ bisect=(searched+endsearched)/2;
+ }
+
+ _seek_helper(vf,bisect);
+ ret=_get_next_page(vf,&og,-1);
+ if(ret==OV_EREAD)return OV_EREAD;
+ if(ret<0 || tremor_ogg_page_serialno(&og)!=currentno){
+ endsearched=bisect;
+ if(ret>=0)next=ret;
+ }else{
+ searched=ret+og.header_len+og.body_len;
+ }
+ tremor_ogg_page_release(&og);
}
- (*serialno_list)[(*n)-1] = s;
-}
-
-/* returns nonzero if found */
-static int _lookup_serialno(ogg_uint32_t s, ogg_uint32_t *serialno_list, int n){
- if(serialno_list){
- while(n--){
- if(*serialno_list == s) return 1;
- serialno_list++;
- }
+ _seek_helper(vf,next);
+ ret=_get_next_page(vf,&og,-1);
+ if(ret==OV_EREAD)return OV_EREAD;
+
+ if(searched>=end || ret<0){
+ tremor_ogg_page_release(&og);
+ vf->links=m+1;
+ vf->offsets=_tremor_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
+ vf->serialnos=_tremor_ogg_malloc(vf->links*sizeof(*vf->serialnos));
+ vf->offsets[m+1]=searched;
+ }else{
+ ret=_bisect_forward_serialno(vf,next,vf->offset,
+ end,tremor_ogg_page_serialno(&og),m+1);
+ tremor_ogg_page_release(&og);
+ if(ret==OV_EREAD)return OV_EREAD;
}
+
+ vf->offsets[m]=begin;
+ vf->serialnos[m]=currentno;
return 0;
}
-static int _lookup_page_serialno(ogg_page *og, ogg_uint32_t *serialno_list, int n){
- ogg_uint32_t s = ogg_page_serialno(og);
- return _lookup_serialno(s,serialno_list,n);
-}
-
-/* performs the same search as _get_prev_page, but prefers pages of
- the specified serial number. If a page of the specified serialno is
- spotted during the seek-back-and-read-forward, it will return the
- info of last page of the matching serial number instead of the very
- last page. If no page of the specified serialno is seen, it will
- return the info of last page and alter *serialno. */
-static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf, ogg_int64_t begin,
- ogg_uint32_t *serial_list, int serial_n,
- int *serialno, ogg_int64_t *granpos){
- ogg_page og;
- ogg_int64_t end=begin;
- ogg_int64_t ret;
-
- ogg_int64_t prefoffset=-1;
- ogg_int64_t offset=-1;
- ogg_int64_t ret_serialno=-1;
- ogg_int64_t ret_gran=-1;
-
- while(offset==-1){
- begin-=CHUNKSIZE;
- if(begin<0)
- begin=0;
-
- ret=_seek_helper(vf,begin);
- if(ret)return(ret);
-
- while(vf->offset<end){
- ret=_get_next_page(vf,&og,end-vf->offset);
- if(ret==OV_EREAD)return(OV_EREAD);
- if(ret<0){
- break;
- }else{
- ret_serialno=ogg_page_serialno(&og);
- ret_gran=ogg_page_granulepos(&og);
- offset=ret;
-
- if((ogg_uint32_t)ret_serialno == *serialno){
- prefoffset=ret;
- *granpos=ret_gran;
- }
-
- if(!_lookup_serialno((ogg_uint32_t)ret_serialno,serial_list,serial_n)){
- /* we fell off the end of the link, which means we seeked
- back too far and shouldn't have been looking in that link
- to begin with. If we found the preferred serial number,
- forget that we saw it. */
- prefoffset=-1;
- }
- }
- }
+static int _decode_clear(TremorOggVorbis_File *vf){
+ if(vf->ready_state==INITSET){
+ vorbis_dsp_destroy(vf->vd);
+ vf->vd=0;
+ vf->ready_state=STREAMSET;
}
-
- /* we're not interested in the page... just the serialno and granpos. */
- if(prefoffset>=0)return(prefoffset);
-
- *serialno = ret_serialno;
- *granpos = ret_gran;
- return(offset);
-
+
+ if(vf->ready_state>=STREAMSET){
+ vorbis_info_clear(&vf->vi);
+ vorbis_comment_clear(&vf->vc);
+ vf->ready_state=OPENED;
+ }
+ return 0;
}
-/* uses the local ogg_stream storage in vf; this is important for
+/* uses the local tremor_ogg_stream storage in vf; this is important for
non-streaming input sources */
-static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
- ogg_uint32_t **serialno_list, int *serialno_n,
- ogg_page *og_ptr){
- ogg_page og;
- ogg_packet op;
+/* consumes the page that's passed in (if any) */
+/* state is LINKSET upon successful return */
+
+static int _fetch_headers(TremorOggVorbis_File *vf,
+ vorbis_info *vi,
+ vorbis_comment *vc,
+ tremor_ogg_uint32_t *serialno,
+ tremor_ogg_page *og_ptr){
+ tremor_ogg_page og={0,0,0,0};
+ tremor_ogg_packet op={0,0,0,0,0,0};
int i,ret;
- int allbos=0;
+
+ if(vf->ready_state>OPENED)_decode_clear(vf);
if(!og_ptr){
- ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
- if(llret==OV_EREAD)return(OV_EREAD);
- if(llret<0)return(OV_ENOTVORBIS);
+ tremor_ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
+ if(llret==OV_EREAD)return OV_EREAD;
+ if(llret<0)return OV_ENOTVORBIS;
og_ptr=&og;
}
+ tremor_ogg_stream_reset_serialno(vf->os,tremor_ogg_page_serialno(og_ptr));
+ if(serialno)*serialno=vf->os->serialno;
+
+ /* extract the initial header from the first page and verify that the
+ Ogg bitstream is in fact Vorbis data */
+
vorbis_info_init(vi);
vorbis_comment_init(vc);
- vf->ready_state=OPENED;
-
- /* extract the serialnos of all BOS pages + the first set of vorbis
- headers we see in the link */
-
- while(ogg_page_bos(og_ptr)){
- if(serialno_list){
- if(_lookup_page_serialno(og_ptr,*serialno_list,*serialno_n)){
- /* a dupe serialnumber in an initial header packet set == invalid stream */
- if(*serialno_list)_ogg_free(*serialno_list);
- *serialno_list=0;
- *serialno_n=0;
- ret=OV_EBADHEADER;
- goto bail_header;
+
+ i=0;
+ while(i<3){
+ tremor_ogg_stream_pagein(vf->os,og_ptr);
+ while(i<3){
+ int result=tremor_ogg_stream_packetout(vf->os,&op);
+ if(result==0)break;
+ if(result==-1){
+ ret=OV_EBADHEADER;
+ goto bail_header;
}
-
- _add_serialno(og_ptr,serialno_list,serialno_n);
- }
-
- if(vf->ready_state<STREAMSET){
- /* we don't have a vorbis stream in this link yet, so begin
- prospective stream setup. We need a stream to get packets */
- ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
- ogg_stream_pagein(&vf->os,og_ptr);
-
- if(ogg_stream_packetout(&vf->os,&op) > 0 &&
- vorbis_synthesis_idheader(&op)){
- /* vorbis header; continue setup */
- vf->ready_state=STREAMSET;
- if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
- ret=OV_EBADHEADER;
- goto bail_header;
- }
+ if((ret=vorbis_dsp_headerin(vi,vc,&op))){
+ goto bail_header;
}
+ i++;
}
-
- /* get next page */
- {
- ogg_int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE);
- if(llret==OV_EREAD){
- ret=OV_EREAD;
- goto bail_header;
- }
- if(llret<0){
- ret=OV_ENOTVORBIS;
- goto bail_header;
+ if(i<3)
+ if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
+ ret=OV_EBADHEADER;
+ goto bail_header;
}
-
- /* if this page also belongs to our vorbis stream, submit it and break */
- if(vf->ready_state==STREAMSET &&
- vf->os.serialno == ogg_page_serialno(og_ptr)){
- ogg_stream_pagein(&vf->os,og_ptr);
- break;
- }
- }
}
- if(vf->ready_state!=STREAMSET){
- ret = OV_ENOTVORBIS;
- goto bail_header;
- }
-
- while(1){
-
- i=0;
- while(i<2){ /* get a page loop */
-
- while(i<2){ /* get a packet loop */
-
- int result=ogg_stream_packetout(&vf->os,&op);
- if(result==0)break;
- if(result==-1){
- ret=OV_EBADHEADER;
- goto bail_header;
- }
-
- if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
- goto bail_header;
-
- i++;
- }
-
- while(i<2){
- if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
- ret=OV_EBADHEADER;
- goto bail_header;
- }
-
- /* if this page belongs to the correct stream, go parse it */
- if(vf->os.serialno == ogg_page_serialno(og_ptr)){
- ogg_stream_pagein(&vf->os,og_ptr);
- break;
- }
-
- /* if we never see the final vorbis headers before the link
- ends, abort */
- if(ogg_page_bos(og_ptr)){
- if(allbos){
- ret = OV_EBADHEADER;
- goto bail_header;
- }else
- allbos=1;
- }
-
- /* otherwise, keep looking */
- }
- }
-
- return 0;
- }
+ tremor_ogg_packet_release(&op);
+ tremor_ogg_page_release(&og);
+ vf->ready_state=LINKSET;
+ return 0;
bail_header:
+ tremor_ogg_packet_release(&op);
+ tremor_ogg_page_release(&og);
vorbis_info_clear(vi);
vorbis_comment_clear(vc);
vf->ready_state=OPENED;
@@ -409,401 +320,321 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
return ret;
}
-/* Starting from current cursor position, get initial PCM offset of
- next page. Consumes the page in the process without decoding
- audio, however this is only called during stream parsing upon
- seekable open. */
-static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
- ogg_page og;
- ogg_int64_t accumulated=0;
- long lastblock=-1;
- int result;
- int serialno = vf->os.serialno;
-
- while(1){
- ogg_packet op;
- if(_get_next_page(vf,&og,-1)<0)
- break; /* should not be possible unless the file is truncated/mangled */
-
- if(ogg_page_bos(&og)) break;
- if(ogg_page_serialno(&og)!=serialno) continue;
-
- /* count blocksizes of all frames in the page */
- ogg_stream_pagein(&vf->os,&og);
- while((result=ogg_stream_packetout(&vf->os,&op))){
- if(result>0){ /* ignore holes */
- long thisblock=vorbis_packet_blocksize(vi,&op);
- if(lastblock!=-1)
- accumulated+=(lastblock+thisblock)>>2;
- lastblock=thisblock;
- }
- }
-
- if(ogg_page_granulepos(&og)!=-1){
- /* pcm offset of last packet on the first audio page */
- accumulated= ogg_page_granulepos(&og)-accumulated;
- break;
- }
+/* we no longer preload all vorbis_info (and the associated
+ codec_setup) structs. Call this to seek and fetch the info from
+ the bitstream, if needed */
+static int _set_link_number(TremorOggVorbis_File *vf,int link){
+ if(link != vf->current_link) _decode_clear(vf);
+ if(vf->ready_state<STREAMSET){
+ _seek_helper(vf,vf->offsets[link]);
+ tremor_ogg_stream_reset_serialno(vf->os,vf->serialnos[link]);
+ vf->current_serialno=vf->serialnos[link];
+ vf->current_link=link;
+ return _fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL);
}
-
- /* less than zero? This is a stream with samples trimmed off
- the beginning, a normal occurrence; set the offset to zero */
- if(accumulated<0)accumulated=0;
-
- return accumulated;
+ return 0;
}
-/* finds each bitstream link one at a time using a bisection search
- (has to begin by knowing the offset of the lb's initial page).
- Recurses for each link so it can alloc the link storage after
- finding them all, then unroll and fill the cache at the same time */
-static int _bisect_forward_serialno(OggVorbis_File *vf,
- ogg_int64_t begin,
- ogg_int64_t searched,
- ogg_int64_t end,
- ogg_int64_t endgran,
- int endserial,
- ogg_uint32_t *currentno_list,
- int currentnos,
- long m){
- ogg_int64_t pcmoffset;
- ogg_int64_t dataoffset=searched;
- ogg_int64_t endsearched=end;
- ogg_int64_t next=end;
- ogg_int64_t searchgran=-1;
- ogg_page og;
- ogg_int64_t ret,last;
- int serialno = vf->os.serialno;
-
- /* invariants:
- we have the headers and serialnos for the link beginning at 'begin'
- we have the offset and granpos of the last page in the file (potentially
- not a page we care about)
- */
-
- /* Is the last page in our list of current serialnumbers? */
- if(_lookup_serialno(endserial,currentno_list,currentnos)){
-
- /* last page is in the starting serialno list, so we've bisected
- down to (or just started with) a single link. Now we need to
- find the last vorbis page belonging to the first vorbis stream
- for this link. */
- searched = end;
- while(endserial != serialno){
- endserial = serialno;
- searched=_get_prev_page_serial(vf,searched,currentno_list,currentnos,&endserial,&endgran);
- }
-
- vf->links=m+1;
- if(vf->offsets)_ogg_free(vf->offsets);
- if(vf->serialnos)_ogg_free(vf->serialnos);
- if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
-
- vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
- vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
- vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
- vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
- vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
- vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
-
- vf->offsets[m+1]=end;
- vf->offsets[m]=begin;
- vf->pcmlengths[m*2+1]=(endgran<0?0:endgran);
-
- }else{
-
- /* last page is not in the starting stream's serial number list,
- so we have multiple links. Find where the stream that begins
- our bisection ends. */
-
- ogg_uint32_t *next_serialno_list=NULL;
- int next_serialnos=0;
- vorbis_info vi;
- vorbis_comment vc;
- int testserial = serialno+1;
+static int _set_link_number_preserve_pos(TremorOggVorbis_File *vf,int link){
+ tremor_ogg_int64_t pos=vf->offset;
+ int ret=_set_link_number(vf,link);
+ if(ret)return ret;
+ _seek_helper(vf,pos);
+ if(pos<vf->offsets[link] || pos>=vf->offsets[link+1])
+ vf->ready_state=STREAMSET;
+ return 0;
+}
- /* the below guards against garbage seperating the last and
- first pages of two links. */
- while(searched<endsearched){
- ogg_int64_t bisect;
+/* last step of the TremorOggVorbis_File initialization; get all the offset
+ positions. Only called by the seekable initialization (local
+ stream storage is hacked slightly; pay attention to how that's
+ done) */
+
+/* this is void and does not propogate errors up because we want to be
+ able to open and use damaged bitstreams as well as we can. Just
+ watch out for missing information for links in the TremorOggVorbis_File
+ struct */
+static void _prefetch_all_offsets(TremorOggVorbis_File *vf, tremor_ogg_int64_t dataoffset){
+ tremor_ogg_page og={0,0,0,0};
+ int i;
+ tremor_ogg_int64_t ret;
+
+ vf->dataoffsets=_tremor_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
+ vf->pcmlengths=_tremor_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
+
+ for(i=0;i<vf->links;i++){
+ if(i==0){
+ /* we already grabbed the initial header earlier. Just set the offset */
+ vf->dataoffsets[i]=dataoffset;
+ _seek_helper(vf,dataoffset);
- if(endsearched-searched<CHUNKSIZE){
- bisect=searched;
- }else{
- bisect=(searched+endsearched)/2;
- }
+ }else{
- ret=_seek_helper(vf,bisect);
- if(ret)return(ret);
+ /* seek to the location of the initial header */
- last=_get_next_page(vf,&og,-1);
- if(last==OV_EREAD)return(OV_EREAD);
- if(last<0 || !_lookup_page_serialno(&og,currentno_list,currentnos)){
- endsearched=bisect;
- if(last>=0)next=last;
+ _seek_helper(vf,vf->offsets[i]);
+ if(_fetch_headers(vf,&vf->vi,&vf->vc,NULL,NULL)<0){
+ vf->dataoffsets[i]=-1;
}else{
- searched=vf->offset;
+ vf->dataoffsets[i]=vf->offset;
}
}
- /* Bisection point found */
- /* for the time being, fetch end PCM offset the simple way */
- searched = next;
- while(testserial != serialno){
- testserial = serialno;
- searched = _get_prev_page_serial(vf,searched,currentno_list,currentnos,&testserial,&searchgran);
- }
-
- ret=_seek_helper(vf,next);
- if(ret)return(ret);
+ /* fetch beginning PCM offset */
- ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
- if(ret)return(ret);
- serialno = vf->os.serialno;
- dataoffset = vf->offset;
+ if(vf->dataoffsets[i]!=-1){
+ tremor_ogg_int64_t accumulated=0,pos;
+ long lastblock=-1;
+ int result;
- /* this will consume a page, however the next bisection always
- starts with a raw seek */
- pcmoffset = _initial_pcmoffset(vf,&vi);
+ tremor_ogg_stream_reset_serialno(vf->os,vf->serialnos[i]);
- ret=_bisect_forward_serialno(vf,next,vf->offset,end,endgran,endserial,
- next_serialno_list,next_serialnos,m+1);
- if(ret)return(ret);
-
- if(next_serialno_list)_ogg_free(next_serialno_list);
+ while(1){
+ tremor_ogg_packet op={0,0,0,0,0,0};
+
+ ret=_get_next_page(vf,&og,-1);
+ if(ret<0)
+ /* this should not be possible unless the file is
+ truncated/mangled */
+ break;
+
+ if(tremor_ogg_page_serialno(&og)!=vf->serialnos[i])
+ break;
+
+ pos=tremor_ogg_page_granulepos(&og);
+
+ /* count blocksizes of all frames in the page */
+ tremor_ogg_stream_pagein(vf->os,&og);
+ while((result=tremor_ogg_stream_packetout(vf->os,&op))){
+ if(result>0){ /* ignore holes */
+ long thisblock=vorbis_packet_blocksize(&vf->vi,&op);
+ if(lastblock!=-1)
+ accumulated+=(lastblock+thisblock)>>2;
+ lastblock=thisblock;
+ }
+ }
+ tremor_ogg_packet_release(&op);
+
+ if(pos!=-1){
+ /* pcm offset of last packet on the first audio page */
+ accumulated= pos-accumulated;
+ break;
+ }
+ }
- vf->offsets[m+1]=next;
- vf->serialnos[m+1]=serialno;
- vf->dataoffsets[m+1]=dataoffset;
+ /* less than zero? This is a stream with samples trimmed off
+ the beginning, a normal occurrence; set the offset to zero */
+ if(accumulated<0)accumulated=0;
- vf->vi[m+1]=vi;
- vf->vc[m+1]=vc;
+ vf->pcmlengths[i*2]=accumulated;
+ }
- vf->pcmlengths[m*2+1]=searchgran;
- vf->pcmlengths[m*2+2]=pcmoffset;
- vf->pcmlengths[m*2+3]-=pcmoffset;
- if(vf->pcmlengths[m*2+3]<0)vf->pcmlengths[m*2+3]=0;
+ /* get the PCM length of this link. To do this,
+ get the last page of the stream */
+ {
+ tremor_ogg_int64_t end=vf->offsets[i+1];
+ _seek_helper(vf,end);
+ while(1){
+ ret=_get_prev_page(vf,&og);
+ if(ret<0){
+ /* this should not be possible */
+ vorbis_info_clear(&vf->vi);
+ vorbis_comment_clear(&vf->vc);
+ break;
+ }
+ if(tremor_ogg_page_granulepos(&og)!=-1){
+ vf->pcmlengths[i*2+1]=tremor_ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
+ break;
+ }
+ vf->offset=ret;
+ }
+ }
}
- return(0);
+ tremor_ogg_page_release(&og);
}
-static int _make_decode_ready(OggVorbis_File *vf){
- if(vf->ready_state>STREAMSET)return 0;
- if(vf->ready_state<STREAMSET)return OV_EFAULT;
- if(vf->seekable){
- if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
- return OV_EBADLINK;
- }else{
- if(vorbis_synthesis_init(&vf->vd,vf->vi))
- return OV_EBADLINK;
+static int _make_decode_ready(TremorOggVorbis_File *vf){
+ int i;
+ switch(vf->ready_state){
+ case OPENED:
+ case STREAMSET:
+ for(i=0;i<vf->links;i++)
+ if(vf->offsets[i+1]>=vf->offset)break;
+ if(i==vf->links)return -1;
+ i=_set_link_number_preserve_pos(vf,i);
+ if(i)return i;
+ /* fall through */
+ case LINKSET:
+ vf->vd=vorbis_dsp_create(&vf->vi);
+ vf->ready_state=INITSET;
+ vf->bittrack=0;
+ vf->samptrack=0;
+ case INITSET:
+ return 0;
+ default:
+ return -1;
}
- vorbis_block_init(&vf->vd,&vf->vb);
- vf->ready_state=INITSET;
- vf->bittrack=0;
- vf->samptrack=0;
- return 0;
+
}
-static int _open_seekable2(OggVorbis_File *vf){
- ogg_int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1;
- int endserial=vf->os.serialno;
- int serialno=vf->os.serialno;
+static int _open_seekable2(TremorOggVorbis_File *vf){
+ tremor_ogg_uint32_t serialno=vf->current_serialno;
+ tremor_ogg_uint32_t tempserialno;
+ tremor_ogg_int64_t dataoffset=vf->offset, end;
+ tremor_ogg_page og={0,0,0,0};
/* we're partially open and have a first link header state in
storage in vf */
-
- /* fetch initial PCM offset */
- ogg_int64_t pcmoffset = _initial_pcmoffset(vf,vf->vi);
-
/* we can seek, so set out learning all about this file */
- if(vf->callbacks.seek_func && vf->callbacks.tell_func){
- (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
- vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
- }else{
- vf->offset=vf->end=-1;
- }
+ (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
+ vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
+
+ /* We get the offset for the last page of the physical bitstream.
+ Most TremorOggVorbis files will contain a single logical bitstream */
+ end=_get_prev_page(vf,&og);
+ if(end<0)return end;
- /* If seek_func is implemented, tell_func must also be implemented */
- if(vf->end==-1) return(OV_EINVAL);
+ /* more than one logical bitstream? */
+ tempserialno=tremor_ogg_page_serialno(&og);
+ tremor_ogg_page_release(&og);
- /* Get the offset of the last page of the physical bitstream, or, if
- we're lucky the last vorbis page of this link as most OggVorbis
- files will contain a single logical bitstream */
- end=_get_prev_page_serial(vf,vf->end,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
- if(end<0)return(end);
+ if(tempserialno!=serialno){
- /* now determine bitstream structure recursively */
- if(_bisect_forward_serialno(vf,0,dataoffset,end,endgran,endserial,
- vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
+ /* Chained bitstream. Bisect-search each logical bitstream
+ section. Do so based on serial number only */
+ if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return OV_EREAD;
- vf->offsets[0]=0;
- vf->serialnos[0]=serialno;
- vf->dataoffsets[0]=dataoffset;
- vf->pcmlengths[0]=pcmoffset;
- vf->pcmlengths[1]-=pcmoffset;
- if(vf->pcmlengths[1]<0)vf->pcmlengths[1]=0;
+ }else{
- return(ov_raw_seek(vf,dataoffset));
-}
+ /* Only one logical bitstream */
+ if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return OV_EREAD;
-/* clear out the current logical bitstream decoder */
-static void _decode_clear(OggVorbis_File *vf){
- vorbis_dsp_clear(&vf->vd);
- vorbis_block_clear(&vf->vb);
- vf->ready_state=OPENED;
+ }
+
+ /* the initial header memory is referenced by vf after; don't free it */
+ _prefetch_all_offsets(vf,dataoffset);
+ return ov_raw_seek(vf,0);
}
/* fetch and process a packet. Handles the case where we're at a
bitstream boundary and dumps the decoding machine. If the decoding
machine is unloaded, it loads it. It also keeps pcm_offset up to
date (seek and read both use this. seek uses a special hack with
- readp).
+ readp).
return: <0) error, OV_HOLE (lost packet) or OV_EOF
0) need more data (only if readp==0)
- 1) got a packet
+ 1) got a packet
*/
-static int _fetch_and_process_packet(OggVorbis_File *vf,
- ogg_packet *op_in,
- int readp,
- int spanp){
- ogg_page og;
+static int _fetch_and_process_packet(TremorOggVorbis_File *vf,
+ int readp,
+ int spanp){
+ tremor_ogg_page og={0,0,0,0};
+ tremor_ogg_packet op={0,0,0,0,0,0};
+ int ret=0;
/* handle one packet. Try to fetch it from current stream state */
/* extract packets from page */
while(1){
-
- if(vf->ready_state==STREAMSET){
- int ret=_make_decode_ready(vf);
- if(ret<0)return ret;
- }
-
+
/* process a packet if we can. If the machine isn't loaded,
neither is a page */
if(vf->ready_state==INITSET){
while(1) {
- ogg_packet op;
- ogg_packet *op_ptr=(op_in?op_in:&op);
- int result=ogg_stream_packetout(&vf->os,op_ptr);
- ogg_int64_t granulepos;
-
- op_in=NULL;
- if(result==-1)return(OV_HOLE); /* hole in the data. */
- if(result>0){
- /* got a packet. process it */
- granulepos=op_ptr->granulepos;
- if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
- header handling. The
- header packets aren't
- audio, so if/when we
- submit them,
- vorbis_synthesis will
- reject them */
-
- /* suck in the synthesis data and track bitrate */
- {
- int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
- /* for proper use of libvorbis within libvorbisfile,
- oldsamples will always be zero. */
- if(oldsamples)return(OV_EFAULT);
-
- vorbis_synthesis_blockin(&vf->vd,&vf->vb);
- vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL);
- vf->bittrack+=op_ptr->bytes*8;
- }
-
- /* update the pcm offset. */
- if(granulepos!=-1 && !op_ptr->e_o_s){
- int link=(vf->seekable?vf->current_link:0);
- int i,samples;
-
- /* this packet has a pcm_offset on it (the last packet
- completed on a page carries the offset) After processing
- (above), we know the pcm position of the *last* sample
- ready to be returned. Find the offset of the *first*
-
- As an aside, this trick is inaccurate if we begin
- reading anew right at the last page; the end-of-stream
- 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 granulepos from an in-sequence page
- to have a reference point. Thus the !op_ptr->e_o_s clause
- above */
-
- if(vf->seekable && link>0)
- granulepos-=vf->pcmlengths[link*2];
- if(granulepos<0)granulepos=0; /* actually, this
- shouldn't be possible
- here unless the stream
- is very broken */
-
- samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
-
- granulepos-=samples;
- for(i=0;i<link;i++)
- granulepos+=vf->pcmlengths[i*2+1];
- vf->pcm_offset=granulepos;
- }
- return(1);
- }
- }
- else
- break;
+ int result=tremor_ogg_stream_packetout(vf->os,&op);
+ tremor_ogg_int64_t granulepos;
+
+ if(result<0){
+ ret=OV_HOLE; /* hole in the data. */
+ goto cleanup;
+ }
+ if(result>0){
+ /* got a packet. process it */
+ granulepos=op.granulepos;
+ if(!vorbis_dsp_synthesis(vf->vd,&op,1)){ /* lazy check for lazy
+ header handling. The
+ header packets aren't
+ audio, so if/when we
+ submit them,
+ vorbis_synthesis will
+ reject them */
+
+ vf->samptrack+=vorbis_dsp_pcmout(vf->vd,NULL,0);
+ vf->bittrack+=op.bytes*8;
+
+ /* update the pcm offset. */
+ if(granulepos!=-1 && !op.e_o_s){
+ int link=(vf->seekable?vf->current_link:0);
+ int i,samples;
+
+ /* this packet has a pcm_offset on it (the last packet
+ completed on a page carries the offset) After processing
+ (above), we know the pcm position of the *last* sample
+ ready to be returned. Find the offset of the *first*
+
+ As an aside, this trick is inaccurate if we begin
+ reading anew right at the last page; the end-of-stream
+ 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 granulepos from an in-sequence page
+ to have a reference point. Thus the !op.e_o_s clause
+ above */
+
+ if(vf->seekable && link>0)
+ granulepos-=vf->pcmlengths[link*2];
+ if(granulepos<0)granulepos=0; /* actually, this
+ shouldn't be possible
+ here unless the stream
+ is very broken */
+
+ samples=vorbis_dsp_pcmout(vf->vd,NULL,0);
+
+ granulepos-=samples;
+ for(i=0;i<link;i++)
+ granulepos+=vf->pcmlengths[i*2+1];
+ vf->pcm_offset=granulepos;
+ }
+ ret=1;
+ goto cleanup;
+ }
+ }
+ else
+ break;
}
}
if(vf->ready_state>=OPENED){
- ogg_int64_t ret;
+ int ret;
+ if(!readp){
+ ret=0;
+ goto cleanup;
+ }
+ if((ret=_get_next_page(vf,&og,-1))<0){
+ ret=OV_EOF; /* eof. leave unitialized */
+ goto cleanup;
+ }
- while(1){
- /* the loop is not strictly necessary, but there's no sense in
- doing the extra checks of the larger loop for the common
- case in a multiplexed bistream where the page is simply
- part of a different logical bitstream; keep reading until
- we get one with the correct serialno */
-
- if(!readp)return(0);
- if((ret=_get_next_page(vf,&og,-1))<0){
- return(OV_EOF); /* eof. leave unitialized */
- }
-
- /* bitrate tracking; add the header's bytes here, the body bytes
- are done by packet above */
- vf->bittrack+=og.header_len*8;
-
- if(vf->ready_state==INITSET){
- if(vf->current_serialno!=ogg_page_serialno(&og)){
-
- /* two possibilities:
- 1) our decoding just traversed a bitstream boundary
- 2) another stream is multiplexed into this logical section */
-
- if(ogg_page_bos(&og)){
- /* boundary case */
- if(!spanp)
- return(OV_EOF);
-
- _decode_clear(vf);
-
- if(!vf->seekable){
- vorbis_info_clear(vf->vi);
- vorbis_comment_clear(vf->vc);
- }
- break;
-
- }else
- continue; /* possibility #2 */
- }
- }
-
- break;
+ /* bitrate tracking; add the header's bytes here, the body bytes
+ are done by packet above */
+ vf->bittrack+=og.header_len*8;
+
+ /* has our decoding just traversed a bitstream boundary? */
+ if(vf->ready_state==INITSET){
+ if(vf->current_serialno!=tremor_ogg_page_serialno(&og)){
+ if(!spanp){
+ ret=OV_EOF;
+ goto cleanup;
+ }
+
+ _decode_clear(vf);
+ }
}
}
/* Do we need to load a new machine before submitting the page? */
- /* This is different in the seekable and non-seekable cases.
+ /* This is different in the seekable and non-seekable cases.
In the seekable case, we already have all the header
information loaded and cached; we just initialize the machine
@@ -814,79 +645,80 @@ static int _fetch_and_process_packet(OggVorbis_File *vf,
we're now nominally at the header of the next bitstream
*/
- if(vf->ready_state!=INITSET){
- int link;
+ if(vf->ready_state!=INITSET){
+ int link,ret;
if(vf->ready_state<STREAMSET){
- if(vf->seekable){
- ogg_uint32_t serialno = ogg_page_serialno(&og);
-
- /* match the serialno to bitstream section. We use this rather than
- offset positions to avoid problems near logical bitstream
- boundaries */
-
- for(link=0;link<vf->links;link++)
- if(vf->serialnos[link]==serialno)break;
-
- if(link==vf->links) continue; /* not the desired Vorbis
- bitstream section; keep
- trying */
-
- vf->current_serialno=serialno;
- vf->current_link=link;
-
- ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
- vf->ready_state=STREAMSET;
-
- }else{
- /* we're streaming */
- /* fetch the three header packets, build the info struct */
-
- int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
- if(ret)return(ret);
- vf->current_serialno=vf->os.serialno;
- vf->current_link++;
- link=0;
- }
+ if(vf->seekable){
+ vf->current_serialno=tremor_ogg_page_serialno(&og);
+
+ /* match the serialno to bitstream section. We use this rather than
+ offset positions to avoid problems near logical bitstream
+ boundaries */
+ for(link=0;link<vf->links;link++)
+ if(vf->serialnos[link]==vf->current_serialno)break;
+ if(link==vf->links){
+ ret=OV_EBADLINK; /* sign of a bogus stream. error out,
+ leave machine uninitialized */
+ goto cleanup;
+ }
+
+ vf->current_link=link;
+ ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
+ if(ret) goto cleanup;
+
+ }else{
+ /* we're streaming */
+ /* fetch the three header packets, build the info struct */
+
+ int ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
+ if(ret) goto cleanup;
+ vf->current_link++;
+ }
}
+
+ if(_make_decode_ready(vf)) return OV_EBADLINK;
}
-
- /* the buffered page is the data we want, and we're ready for it;
- add it to the stream state */
- ogg_stream_pagein(&vf->os,&og);
-
+ tremor_ogg_stream_pagein(vf->os,&og);
}
+ cleanup:
+ tremor_ogg_packet_release(&op);
+ tremor_ogg_page_release(&og);
+ return ret;
}
/* if, eg, 64 bit stdio is configured by default, this will build with
fseek64 */
-static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
- if(f==NULL)return(-1);
+static int _fseek64_wrap(FILE *f,tremor_ogg_int64_t off,int whence){
+ if(f==NULL)return -1;
return fseek(f,off,whence);
}
-static int _ov_open1(void *f,OggVorbis_File *vf,const char *initial,
- long ibytes, ov_callbacks callbacks){
- int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
- ogg_uint32_t *serialno_list=NULL;
- int serialno_list_size=0;
+static int _ov_open1(void *f,TremorOggVorbis_File *vf,char *initial,
+ long ibytes, ov_callbacks callbacks){
+ int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
int ret;
memset(vf,0,sizeof(*vf));
+
+ /* Tremor assumes in multiple places that right shift of a signed
+ integer is an arithmetic shift */
+ if( (-1>>1) != -1) return OV_EIMPL;
+
vf->datasource=f;
vf->callbacks = callbacks;
/* init the framing state */
- ogg_sync_init(&vf->oy);
+ vf->oy=tremor_ogg_sync_create();
/* perhaps some data was previously read into a buffer for testing
against other stream types. Allow initialization from this
- previously read data (especially as we may be reading from a
- non-seekable stream) */
+ previously read data (as we may be reading from a non-seekable
+ stream) */
if(initial){
- char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
+ unsigned char *buffer=tremor_ogg_sync_bufferin(vf->oy,ibytes);
memcpy(buffer,initial,ibytes);
- ogg_sync_wrote(&vf->oy,ibytes);
+ tremor_ogg_sync_wrote(vf->oy,ibytes);
}
/* can we seek? Stevens suggests the seek test was portable */
@@ -895,154 +727,115 @@ static int _ov_open1(void *f,OggVorbis_File *vf,const char *initial,
/* No seeking yet; Set up a 'single' (current) logical bitstream
entry for partial open */
vf->links=1;
- vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
- vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
- ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
+ vf->os=tremor_ogg_stream_create(-1); /* fill in the serialno later */
- /* Fetch all BOS pages, store the vorbis header and all seen serial
- numbers, load subsequent vorbis setup headers */
- if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){
+ /* Try to fetch the headers, maintaining all the storage */
+ if((ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL))<0){
vf->datasource=NULL;
ov_clear(vf);
- }else{
- /* serial number list for first link needs to be held somewhere
- for second stage of seekable stream open; this saves having to
- seek/reread first link's serialnumber data then. */
- vf->serialnos=_ogg_calloc(serialno_list_size+2,sizeof(*vf->serialnos));
- vf->serialnos[0]=vf->current_serialno=vf->os.serialno;
- vf->serialnos[1]=serialno_list_size;
- memcpy(vf->serialnos+2,serialno_list,serialno_list_size*sizeof(*vf->serialnos));
-
- vf->offsets=_ogg_calloc(1,sizeof(*vf->offsets));
- vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets));
- vf->offsets[0]=0;
- vf->dataoffsets[0]=vf->offset;
-
+ }else if(vf->ready_state < PARTOPEN)
vf->ready_state=PARTOPEN;
- }
- if(serialno_list)_ogg_free(serialno_list);
- return(ret);
+ return ret;
}
-static int _ov_open2(OggVorbis_File *vf){
- if(vf->ready_state != PARTOPEN) return OV_EINVAL;
- vf->ready_state=OPENED;
+static int _ov_open2(TremorOggVorbis_File *vf){
+ if(vf->ready_state < OPENED)
+ vf->ready_state=OPENED;
if(vf->seekable){
int ret=_open_seekable2(vf);
if(ret){
vf->datasource=NULL;
ov_clear(vf);
}
- return(ret);
- }else
- vf->ready_state=STREAMSET;
-
+ return ret;
+ }
return 0;
}
-/* clear out the OggVorbis_File struct */
-int ov_clear(OggVorbis_File *vf){
+/* clear out the TremorOggVorbis_File struct */
+int ov_clear(TremorOggVorbis_File *vf){
if(vf){
- vorbis_block_clear(&vf->vb);
- vorbis_dsp_clear(&vf->vd);
- ogg_stream_clear(&vf->os);
-
- if(vf->vi && vf->links){
- int i;
- for(i=0;i<vf->links;i++){
- vorbis_info_clear(vf->vi+i);
- vorbis_comment_clear(vf->vc+i);
- }
- _ogg_free(vf->vi);
- _ogg_free(vf->vc);
- }
- if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
- if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
- if(vf->serialnos)_ogg_free(vf->serialnos);
- if(vf->offsets)_ogg_free(vf->offsets);
- ogg_sync_clear(&vf->oy);
- if(vf->datasource && vf->callbacks.close_func)
- (vf->callbacks.close_func)(vf->datasource);
+ vorbis_dsp_destroy(vf->vd);
+ vf->vd=0;
+ tremor_ogg_stream_destroy(vf->os);
+ vorbis_info_clear(&vf->vi);
+ vorbis_comment_clear(&vf->vc);
+ if(vf->dataoffsets)_tremor_ogg_free(vf->dataoffsets);
+ if(vf->pcmlengths)_tremor_ogg_free(vf->pcmlengths);
+ if(vf->serialnos)_tremor_ogg_free(vf->serialnos);
+ if(vf->offsets)_tremor_ogg_free(vf->offsets);
+ tremor_ogg_sync_destroy(vf->oy);
+
+ if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
memset(vf,0,sizeof(*vf));
}
#ifdef DEBUG_LEAKS
_VDBG_dump();
#endif
- return(0);
+ return 0;
}
-/* inspects the OggVorbis file and finds/documents all the logical
+/* inspects the TremorOggVorbis file and finds/documents all the logical
bitstreams contained in it. Tries to be tolerant of logical
- bitstream sections that are truncated/woogie.
+ bitstream sections that are truncated/woogie.
return: -1) error
0) OK
*/
-int ov_open_callbacks(void *f,OggVorbis_File *vf,
- const char *initial,long ibytes,ov_callbacks callbacks){
+int ov_open_callbacks(void *f,TremorOggVorbis_File *vf,char *initial,long ibytes,
+ ov_callbacks callbacks){
int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
if(ret)return ret;
return _ov_open2(vf);
}
-int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes){
+int ov_open(FILE *f,TremorOggVorbis_File *vf,char *initial,long ibytes){
ov_callbacks callbacks = {
(size_t (*)(void *, size_t, size_t, void *)) fread,
- (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
+ (int (*)(void *, tremor_ogg_int64_t, int)) _fseek64_wrap,
(int (*)(void *)) fclose,
(long (*)(void *)) ftell
};
return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
}
-
-int ov_fopen(const char *path,OggVorbis_File *vf){
- int ret;
- FILE *f = fopen(path,"rb");
- if(!f) return -1;
-
- ret = ov_open(f,vf,NULL,0);
- if(ret) fclose(f);
- return ret;
-}
-
-
+
/* Only partially open the vorbis file; test for Vorbisness, and load
the headers for the first chain. Do not seek (although test for
seekability). Use ov_test_open to finish opening the file, else
ov_clear to close/free it. Same return codes as open. */
-int ov_test_callbacks(void *f,OggVorbis_File *vf,
- const char *initial,long ibytes,ov_callbacks callbacks)
+int ov_test_callbacks(void *f,TremorOggVorbis_File *vf,char *initial,long ibytes,
+ ov_callbacks callbacks)
{
return _ov_open1(f,vf,initial,ibytes,callbacks);
}
-int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes){
+int ov_test(FILE *f,TremorOggVorbis_File *vf,char *initial,long ibytes){
ov_callbacks callbacks = {
(size_t (*)(void *, size_t, size_t, void *)) fread,
- (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
+ (int (*)(void *, tremor_ogg_int64_t, int)) _fseek64_wrap,
(int (*)(void *)) fclose,
(long (*)(void *)) ftell
};
return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
}
-
-int ov_test_open(OggVorbis_File *vf){
- if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
+
+int ov_test_open(TremorOggVorbis_File *vf){
+ if(vf->ready_state!=PARTOPEN)return OV_EINVAL;
return _ov_open2(vf);
}
/* How many logical bitstreams in this physical bitstream? */
-long ov_streams(OggVorbis_File *vf){
+long ov_streams(TremorOggVorbis_File *vf){
return vf->links;
}
/* Is the FILE * associated with vf seekable? */
-long ov_seekable(OggVorbis_File *vf){
+long ov_seekable(TremorOggVorbis_File *vf){
return vf->seekable;
}
@@ -1055,12 +848,12 @@ long ov_seekable(OggVorbis_File *vf){
If you want the actual bitrate field settings, get them from the
vorbis_info structs */
-long ov_bitrate(OggVorbis_File *vf,int i){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(i>=vf->links)return(OV_EINVAL);
- if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
+long ov_bitrate(TremorOggVorbis_File *vf,int i){
+ if(vf->ready_state<OPENED)return OV_EINVAL;
+ if(i>=vf->links)return OV_EINVAL;
+ if(!vf->seekable && i!=0)return ov_bitrate(vf,0);
if(i<0){
- ogg_int64_t bits=0;
+ tremor_ogg_int64_t bits=0;
int i;
for(i=0;i<vf->links;i++)
bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
@@ -1068,24 +861,24 @@ long ov_bitrate(OggVorbis_File *vf,int i){
* gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
* so this is slightly transformed to make it work.
*/
- return(bits*1000/ov_time_total(vf,-1));
+ return bits*1000/ov_time_total(vf,-1);
}else{
if(vf->seekable){
/* return the actual bitrate */
- return((vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i));
+ return (vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i);
}else{
/* return nominal if set */
- if(vf->vi[i].bitrate_nominal>0){
- return vf->vi[i].bitrate_nominal;
+ if(vf->vi.bitrate_nominal>0){
+ return vf->vi.bitrate_nominal;
}else{
- if(vf->vi[i].bitrate_upper>0){
- if(vf->vi[i].bitrate_lower>0){
- return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
- }else{
- return vf->vi[i].bitrate_upper;
- }
- }
- return(OV_FALSE);
+ if(vf->vi.bitrate_upper>0){
+ if(vf->vi.bitrate_lower>0){
+ return (vf->vi.bitrate_upper+vf->vi.bitrate_lower)/2;
+ }else{
+ return vf->vi.bitrate_upper;
+ }
+ }
+ return OV_FALSE;
}
}
}
@@ -1093,84 +886,83 @@ long ov_bitrate(OggVorbis_File *vf,int i){
/* returns the actual bitrate since last call. returns -1 if no
additional data to offer since last call (or at beginning of stream),
- EINVAL if stream is only partially open
+ EINVAL if stream is only partially open
*/
-long ov_bitrate_instant(OggVorbis_File *vf){
- int link=(vf->seekable?vf->current_link:0);
+long ov_bitrate_instant(TremorOggVorbis_File *vf){
long ret;
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(vf->samptrack==0)return(OV_FALSE);
- ret=vf->bittrack/vf->samptrack*vf->vi[link].rate;
+ if(vf->ready_state<OPENED)return OV_EINVAL;
+ if(vf->samptrack==0)return OV_FALSE;
+ ret=vf->bittrack/vf->samptrack*vf->vi.rate;
vf->bittrack=0;
vf->samptrack=0;
- return(ret);
+ return ret;
}
/* Guess */
-long ov_serialnumber(OggVorbis_File *vf,int i){
- if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
- if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
+long ov_serialnumber(TremorOggVorbis_File *vf,int i){
+ if(i>=vf->links)return ov_serialnumber(vf,vf->links-1);
+ if(!vf->seekable && i>=0)return ov_serialnumber(vf,-1);
if(i<0){
- return(vf->current_serialno);
+ return vf->current_serialno;
}else{
- return(vf->serialnos[i]);
+ return vf->serialnos[i];
}
}
/* returns: total raw (compressed) length of content if i==-1
raw (compressed) length of that logical bitstream for i==0 to n
- OV_EINVAL if the stream is not seekable (we can't know the length)
- or if stream is only partially open
+ OV_EINVAL if the stream is not seekable (we can't know the length)
+ or if stream is only partially open
*/
-ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
+tremor_ogg_int64_t ov_raw_total(TremorOggVorbis_File *vf,int i){
+ if(vf->ready_state<OPENED)return OV_EINVAL;
+ if(!vf->seekable || i>=vf->links)return OV_EINVAL;
if(i<0){
- ogg_int64_t acc=0;
+ tremor_ogg_int64_t acc=0;
int i;
for(i=0;i<vf->links;i++)
acc+=ov_raw_total(vf,i);
- return(acc);
+ return acc;
}else{
- return(vf->offsets[i+1]-vf->offsets[i]);
+ return vf->offsets[i+1]-vf->offsets[i];
}
}
/* returns: total PCM length (samples) of content if i==-1 PCM length
- (samples) of that logical bitstream for i==0 to n
- OV_EINVAL if the stream is not seekable (we can't know the
- length) or only partially open
+ (samples) of that logical bitstream for i==0 to n
+ OV_EINVAL if the stream is not seekable (we can't know the
+ length) or only partially open
*/
-ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
+tremor_ogg_int64_t ov_pcm_total(TremorOggVorbis_File *vf,int i){
+ if(vf->ready_state<OPENED)return OV_EINVAL;
+ if(!vf->seekable || i>=vf->links)return OV_EINVAL;
if(i<0){
- ogg_int64_t acc=0;
+ tremor_ogg_int64_t acc=0;
int i;
for(i=0;i<vf->links;i++)
acc+=ov_pcm_total(vf,i);
- return(acc);
+ return acc;
}else{
- return(vf->pcmlengths[i*2+1]);
+ return vf->pcmlengths[i*2+1];
}
}
/* returns: total milliseconds of content if i==-1
milliseconds in that logical bitstream for i==0 to n
- OV_EINVAL if the stream is not seekable (we can't know the
- length) or only partially open
+ OV_EINVAL if the stream is not seekable (we can't know the
+ length) or only partially open
*/
-ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
+tremor_ogg_int64_t ov_time_total(TremorOggVorbis_File *vf,int i){
+ if(vf->ready_state<OPENED)return OV_EINVAL;
+ if(!vf->seekable || i>=vf->links)return OV_EINVAL;
if(i<0){
- ogg_int64_t acc=0;
+ tremor_ogg_int64_t acc=0;
int i;
for(i=0;i<vf->links;i++)
acc+=ov_time_total(vf,i);
- return(acc);
+ return acc;
}else{
- return(((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi[i].rate);
+ return ((tremor_ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi.rate;
}
}
@@ -1181,33 +973,27 @@ ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){
returns zero on success, nonzero on failure */
-int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
- ogg_stream_state work_os;
- int ret;
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
+int ov_raw_seek(TremorOggVorbis_File *vf,tremor_ogg_int64_t pos){
+ tremor_ogg_stream_state *work_os=NULL;
+ tremor_ogg_page og={0,0,0,0};
+ tremor_ogg_packet op={0,0,0,0,0,0};
+
+ if(vf->ready_state<OPENED)return OV_EINVAL;
if(!vf->seekable)
- return(OV_ENOSEEK); /* don't dump machine if we can't seek */
-
- if(pos<0 || pos>vf->end)return(OV_EINVAL);
+ return OV_ENOSEEK; /* don't dump machine if we can't seek */
- /* is the seek position outside our current link [if any]? */
- if(vf->ready_state>=STREAMSET){
- if(pos<vf->offsets[vf->current_link] || pos>=vf->offsets[vf->current_link+1])
- _decode_clear(vf); /* clear out stream state */
- }
+ if(pos<0 || pos>vf->end)return OV_EINVAL;
/* don't yet clear out decoding machine (if it's initialized), in
the case we're in the same link. Restart the decode lapping, and
let _fetch_and_process_packet deal with a potential bitstream
boundary */
vf->pcm_offset=-1;
- ogg_stream_reset_serialno(&vf->os,
- vf->current_serialno); /* must set serialno */
- vorbis_synthesis_restart(&vf->vd);
-
- ret=_seek_helper(vf,pos);
- if(ret)goto seek_error;
+ tremor_ogg_stream_reset_serialno(vf->os,
+ vf->current_serialno); /* must set serialno */
+ vorbis_dsp_restart(vf->vd);
+
+ _seek_helper(vf,pos);
/* we need to make sure the pcm_offset is set, but we don't want to
advance the raw cursor past good packets just to get to the first
@@ -1216,428 +1002,281 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
So, a hack. We use two stream states; a local scratch state and
the shared vf->os stream state. We use the local state to
- scan, and the shared state as a buffer for later decode.
+ scan, and the shared state as a buffer for later decode.
Unfortuantely, on the last page we still advance to last packet
because the granulepos on the last page is not necessarily on a
packet boundary, and we need to make sure the granpos is
- correct.
+ correct.
*/
{
- ogg_page og;
- ogg_packet op;
int lastblock=0;
int accblock=0;
- int thisblock=0;
- int lastflag=0;
- int firstflag=0;
- ogg_int64_t pagepos=-1;
-
- ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
- ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
- return from not necessarily
- starting from the beginning */
+ int thisblock;
+ int eosflag;
+ work_os=tremor_ogg_stream_create(vf->current_serialno); /* get the memory ready */
while(1){
if(vf->ready_state>=STREAMSET){
- /* snarf/scan a packet if we can */
- int result=ogg_stream_packetout(&work_os,&op);
-
- if(result>0){
-
- if(vf->vi[vf->current_link].codec_setup){
- thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
- if(thisblock<0){
- ogg_stream_packetout(&vf->os,NULL);
- thisblock=0;
- }else{
-
- /* We can't get a guaranteed correct pcm position out of the
- last page in a stream because it might have a 'short'
- granpos, which can only be detected in the presence of a
- preceding page. However, if the last page is also the first
- page, the granpos rules of a first page take precedence. Not
- only that, but for first==last, the EOS page must be treated
- as if its a normal first page for the stream to open/play. */
- if(lastflag && !firstflag)
- ogg_stream_packetout(&vf->os,NULL);
- else
- if(lastblock)accblock+=(lastblock+thisblock)>>2;
- }
-
- if(op.granulepos!=-1){
- int i,link=vf->current_link;
- ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
- if(granulepos<0)granulepos=0;
-
- for(i=0;i<link;i++)
- granulepos+=vf->pcmlengths[i*2+1];
- vf->pcm_offset=granulepos-accblock;
- if(vf->pcm_offset<0)vf->pcm_offset=0;
- break;
- }
- lastblock=thisblock;
- continue;
- }else
- ogg_stream_packetout(&vf->os,NULL);
- }
+ /* snarf/scan a packet if we can */
+ int result=tremor_ogg_stream_packetout(work_os,&op);
+
+ if(result>0){
+
+ if(vf->vi.codec_setup){
+ thisblock=vorbis_packet_blocksize(&vf->vi,&op);
+ if(thisblock<0){
+ tremor_ogg_stream_packetout(vf->os,NULL);
+ thisblock=0;
+ }else{
+
+ if(eosflag)
+ tremor_ogg_stream_packetout(vf->os,NULL);
+ else
+ if(lastblock)accblock+=(lastblock+thisblock)>>2;
+ }
+
+ if(op.granulepos!=-1){
+ int i,link=vf->current_link;
+ tremor_ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
+ if(granulepos<0)granulepos=0;
+
+ for(i=0;i<link;i++)
+ granulepos+=vf->pcmlengths[i*2+1];
+ vf->pcm_offset=granulepos-accblock;
+ break;
+ }
+ lastblock=thisblock;
+ continue;
+ }else
+ tremor_ogg_stream_packetout(vf->os,NULL);
+ }
}
-
+
if(!lastblock){
- pagepos=_get_next_page(vf,&og,-1);
- if(pagepos<0){
- vf->pcm_offset=ov_pcm_total(vf,-1);
- break;
- }
+ if(_get_next_page(vf,&og,-1)<0){
+ vf->pcm_offset=ov_pcm_total(vf,-1);
+ break;
+ }
}else{
- /* huh? Bogus stream with packets but no granulepos */
- vf->pcm_offset=-1;
- break;
- }
-
- /* has our decoding just traversed a bitstream boundary? */
- if(vf->ready_state>=STREAMSET){
- if(vf->current_serialno!=ogg_page_serialno(&og)){
-
- /* two possibilities:
- 1) our decoding just traversed a bitstream boundary
- 2) another stream is multiplexed into this logical section? */
-
- if(ogg_page_bos(&og)){
- /* we traversed */
- _decode_clear(vf); /* clear out stream state */
- ogg_stream_clear(&work_os);
- } /* else, do nothing; next loop will scoop another page */
- }
+ /* huh? Bogus stream with packets but no granulepos */
+ vf->pcm_offset=-1;
+ break;
}
+
+ /* did we just grab a page from other than current link? */
+ if(vf->ready_state>=STREAMSET)
+ if(vf->current_serialno!=tremor_ogg_page_serialno(&og)){
+ _decode_clear(vf); /* clear out stream state */
+ tremor_ogg_stream_destroy(work_os);
+ }
if(vf->ready_state<STREAMSET){
- int link;
- ogg_uint32_t serialno = ogg_page_serialno(&og);
-
- for(link=0;link<vf->links;link++)
- if(vf->serialnos[link]==serialno)break;
-
- if(link==vf->links) continue; /* not the desired Vorbis
- bitstream section; keep
- trying */
- vf->current_link=link;
- vf->current_serialno=serialno;
- ogg_stream_reset_serialno(&vf->os,serialno);
- ogg_stream_reset_serialno(&work_os,serialno);
- vf->ready_state=STREAMSET;
- firstflag=(pagepos<=vf->dataoffsets[link]);
+ int link;
+
+ vf->current_serialno=tremor_ogg_page_serialno(&og);
+ for(link=0;link<vf->links;link++)
+ if(vf->serialnos[link]==vf->current_serialno)break;
+ if(link==vf->links)
+ goto seek_error; /* sign of a bogus stream. error out,
+ leave machine uninitialized */
+
+ /* need to initialize machine to this link */
+ {
+ int ret=_set_link_number_preserve_pos(vf,link);
+ if(ret) goto seek_error;
+ }
+ tremor_ogg_stream_reset_serialno(vf->os,vf->current_serialno);
+ tremor_ogg_stream_reset_serialno(work_os,vf->current_serialno);
+
+
+ }
+
+ {
+ tremor_ogg_page dup;
+ tremor_ogg_page_dup(&dup,&og);
+ eosflag=tremor_ogg_page_eos(&og);
+ tremor_ogg_stream_pagein(vf->os,&og);
+ tremor_ogg_stream_pagein(work_os,&dup);
}
-
- ogg_stream_pagein(&vf->os,&og);
- ogg_stream_pagein(&work_os,&og);
- lastflag=ogg_page_eos(&og);
-
}
}
- ogg_stream_clear(&work_os);
+ tremor_ogg_packet_release(&op);
+ tremor_ogg_page_release(&og);
+ tremor_ogg_stream_destroy(work_os);
vf->bittrack=0;
vf->samptrack=0;
- return(0);
+ return 0;
seek_error:
+ tremor_ogg_packet_release(&op);
+ tremor_ogg_page_release(&og);
+
/* dump the machine so we're in a known state */
vf->pcm_offset=-1;
- ogg_stream_clear(&work_os);
+ tremor_ogg_stream_destroy(work_os);
_decode_clear(vf);
return OV_EBADLINK;
}
-/* rescales the number x from the range of [0,from] to [0,to]
- x is in the range [0,from]
- from, to are in the range [1, 1<<62-1] */
-ogg_int64_t rescale64(ogg_int64_t x, ogg_int64_t from, ogg_int64_t to){
- ogg_int64_t frac=0;
- ogg_int64_t ret=0;
- int i;
- if(x >= from) return to;
- if(x <= 0) return 0;
-
- for(i=0;i<64;i++){
- if(x>=from){
- frac|=1;
- x-=from;
- }
- x<<=1;
- frac<<=1;
- }
-
- for(i=0;i<64;i++){
- if(frac & 1){
- ret+=to;
- }
- frac>>=1;
- ret>>=1;
- }
-
- return ret;
-}
-
/* Page granularity seek (faster than sample granularity because we
don't do the last bit of decode to find a specific sample).
- Seek to the last [granule marked] page preceding the specified pos
+ Seek to the last [granule marked] page preceeding the specified pos
location, such that decoding past the returned point will quickly
arrive at the requested position. */
-int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
+int ov_pcm_seek_page(TremorOggVorbis_File *vf,tremor_ogg_int64_t pos){
int link=-1;
- ogg_int64_t result=0;
- ogg_int64_t total=ov_pcm_total(vf,-1);
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable)return(OV_ENOSEEK);
-
- if(pos<0 || pos>total)return(OV_EINVAL);
-
+ tremor_ogg_int64_t result=0;
+ tremor_ogg_int64_t total=ov_pcm_total(vf,-1);
+ tremor_ogg_page og={0,0,0,0};
+ tremor_ogg_packet op={0,0,0,0,0,0};
+
+ if(vf->ready_state<OPENED)return OV_EINVAL;
+ if(!vf->seekable)return OV_ENOSEEK;
+ if(pos<0 || pos>total)return OV_EINVAL;
+
/* which bitstream section does this pcm offset occur in? */
for(link=vf->links-1;link>=0;link--){
total-=vf->pcmlengths[link*2+1];
if(pos>=total)break;
}
- /* Search within the logical bitstream for the page with the highest
- pcm_pos preceding pos. If we're looking for a position on the
- first page, bisection will halt without finding our position as
- it's before the first explicit granulepos fencepost. That case is
- handled separately below.
-
- There is a danger here; missing pages or incorrect frame number
- information in the bitstream could make our task impossible.
- Account for that (it would be an error condition) */
- /* new search algorithm originally by HB (Nicholas Vinen) */
-
- {
- ogg_int64_t end=vf->offsets[link+1];
- ogg_int64_t begin=vf->dataoffsets[link];
- ogg_int64_t begintime = vf->pcmlengths[link*2];
- ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
- ogg_int64_t target=pos-total+begintime;
- ogg_int64_t best=-1;
- int got_page=0;
-
- ogg_page og;
-
- /* if we have only one page, there will be no bisection. Grab the page here */
- if(begin==end){
- result=_seek_helper(vf,begin);
- if(result) goto seek_error;
+ if(link!=vf->current_link){
+ int ret=_set_link_number(vf,link);
+ if(ret) goto seek_error;
+ }else{
+ vorbis_dsp_restart(vf->vd);
+ }
- result=_get_next_page(vf,&og,1);
- if(result<0) goto seek_error;
+ tremor_ogg_stream_reset_serialno(vf->os,vf->serialnos[link]);
- got_page=1;
- }
+ /* search within the logical bitstream for the page with the highest
+ pcm_pos preceeding (or equal to) pos. There is a danger here;
+ missing pages or incorrect frame number information in the
+ bitstream could make our task impossible. Account for that (it
+ would be an error condition) */
- /* bisection loop */
+ /* new search algorithm by HB (Nicholas Vinen) */
+ {
+ tremor_ogg_int64_t end=vf->offsets[link+1];
+ tremor_ogg_int64_t begin=vf->offsets[link];
+ tremor_ogg_int64_t begintime = vf->pcmlengths[link*2];
+ tremor_ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
+ tremor_ogg_int64_t target=pos-total+begintime;
+ tremor_ogg_int64_t best=begin;
+
while(begin<end){
- ogg_int64_t bisect;
-
+ tremor_ogg_int64_t bisect;
+
if(end-begin<CHUNKSIZE){
- bisect=begin;
+ bisect=begin;
}else{
- /* take a (pretty decent) guess. */
- bisect=begin + rescale64(target-begintime,
- endtime-begintime,
- end-begin) - CHUNKSIZE;
- if(bisect<begin+CHUNKSIZE)
- bisect=begin;
+ /* take a (pretty decent) guess. */
+ bisect=begin +
+ (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
+ if(bisect<=begin)
+ bisect=begin+1;
}
-
- result=_seek_helper(vf,bisect);
- if(result) goto seek_error;
-
- /* read loop within the bisection loop */
+
+ _seek_helper(vf,bisect);
+
while(begin<end){
- result=_get_next_page(vf,&og,end-vf->offset);
- if(result==OV_EREAD) goto seek_error;
- if(result<0){
- /* there is no next page! */
- if(bisect<=begin+1)
- /* No bisection left to perform. We've either found the
- best candidate already or failed. Exit loop. */
- end=begin;
- else{
- /* We tried to load a fraction of the last page; back up a
- bit and try to get the whole last page */
- if(bisect==0) goto seek_error;
- bisect-=CHUNKSIZE;
-
- /* don't repeat/loop on a read we've already performed */
- if(bisect<=begin)bisect=begin+1;
-
- /* seek and continue bisection */
- result=_seek_helper(vf,bisect);
- if(result) goto seek_error;
- }
- }else{
- ogg_int64_t granulepos;
- got_page=1;
-
- /* got a page. analyze it */
- /* only consider pages from primary vorbis stream */
- if(ogg_page_serialno(&og)!=vf->serialnos[link])
- continue;
-
- /* only consider pages with the granulepos set */
- granulepos=ogg_page_granulepos(&og);
- if(granulepos==-1)continue;
-
- if(granulepos<target){
- /* this page is a successful candidate! Set state */
-
- best=result; /* raw offset of packet with granulepos */
- begin=vf->offset; /* raw offset of next page */
- begintime=granulepos;
-
- /* if we're before our target but within a short distance,
- don't bisect; read forward */
- if(target-begintime>44100)break;
-
- bisect=begin; /* *not* begin + 1 as above */
- }else{
-
- /* This is one of our pages, but the granpos is
- post-target; it is not a bisection return
- candidate. (The only way we'd use it is if it's the
- first page in the stream; we handle that case later
- outside the bisection) */
- if(bisect<=begin+1){
- /* No bisection left to perform. We've either found the
- best candidate already or failed. Exit loop. */
- end=begin;
- }else{
- if(end==vf->offset){
- /* bisection read to the end; use the known page
- boundary (result) to update bisection, back up a
- little bit, and try again */
- end=result;
- bisect-=CHUNKSIZE;
- if(bisect<=begin)bisect=begin+1;
- result=_seek_helper(vf,bisect);
- if(result) goto seek_error;
- }else{
- /* Normal bisection */
- end=bisect;
- endtime=granulepos;
- break;
- }
- }
- }
- }
+ result=_get_next_page(vf,&og,end-vf->offset);
+ if(result==OV_EREAD) goto seek_error;
+ if(result<0){
+ if(bisect<=begin+1)
+ end=begin; /* found it */
+ else{
+ if(bisect==0) goto seek_error;
+ bisect-=CHUNKSIZE;
+ if(bisect<=begin)bisect=begin+1;
+ _seek_helper(vf,bisect);
+ }
+ }else{
+ tremor_ogg_int64_t granulepos=tremor_ogg_page_granulepos(&og);
+ if(granulepos==-1)continue;
+ if(granulepos<target){
+ best=result; /* raw offset of packet with granulepos */
+ begin=vf->offset; /* raw offset of next page */
+ begintime=granulepos;
+
+ if(target-begintime>44100)break;
+ bisect=begin; /* *not* begin + 1 */
+ }else{
+ if(bisect<=begin+1)
+ end=begin; /* found it */
+ else{
+ if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
+ end=result;
+ bisect-=CHUNKSIZE; /* an endless loop otherwise. */
+ if(bisect<=begin)bisect=begin+1;
+ _seek_helper(vf,bisect);
+ }else{
+ end=result;
+ endtime=granulepos;
+ break;
+ }
+ }
+ }
+ }
}
}
- /* Out of bisection: did it 'fail?' */
- if(best == -1){
-
- /* Check the 'looking for data in first page' special case;
- bisection would 'fail' because our search target was before the
- first PCM granule position fencepost. */
-
- if(got_page &&
- begin == vf->dataoffsets[link] &&
- ogg_page_serialno(&og)==vf->serialnos[link]){
-
- /* Yes, this is the beginning-of-stream case. We already have
- our page, right at the beginning of PCM data. Set state
- and return. */
-
- vf->pcm_offset=total;
-
- if(link!=vf->current_link){
- /* Different link; dump entire decode machine */
- _decode_clear(vf);
-
- vf->current_link=link;
- vf->current_serialno=vf->serialnos[link];
- vf->ready_state=STREAMSET;
-
- }else{
- vorbis_synthesis_restart(&vf->vd);
- }
-
- ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
- ogg_stream_pagein(&vf->os,&og);
-
- }else
- goto seek_error;
-
- }else{
-
- /* Bisection found our page. seek to it, update pcm offset. Easier case than
- raw_seek, don't keep packets preceding granulepos. */
-
- ogg_page og;
- ogg_packet op;
-
+ /* found our page. seek to it, update pcm offset. Easier case than
+ raw_seek, don't keep packets preceeding granulepos. */
+ {
+
/* seek */
- result=_seek_helper(vf,best);
+ _seek_helper(vf,best);
vf->pcm_offset=-1;
- if(result) goto seek_error;
- result=_get_next_page(vf,&og,-1);
- if(result<0) goto seek_error;
-
- if(link!=vf->current_link){
- /* Different link; dump entire decode machine */
- _decode_clear(vf);
-
- vf->current_link=link;
- vf->current_serialno=vf->serialnos[link];
- vf->ready_state=STREAMSET;
-
- }else{
- vorbis_synthesis_restart(&vf->vd);
+
+ if(_get_next_page(vf,&og,-1)<0){
+ tremor_ogg_page_release(&og);
+ return OV_EOF; /* shouldn't happen */
}
- ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
- ogg_stream_pagein(&vf->os,&og);
+ tremor_ogg_stream_pagein(vf->os,&og);
/* pull out all but last packet; the one with granulepos */
while(1){
- result=ogg_stream_packetpeek(&vf->os,&op);
- if(result==0){
- /* No packet returned; we exited the bisection with 'best'
- pointing to a page with a granule position, so the packet
- finishing this page ('best') originated on a preceding
- page. Keep fetching previous pages until we get one with
- a granulepos or without the 'continued' flag set. Then
- just use raw_seek for simplicity. */
- /* Do not rewind past the beginning of link data; if we do,
- it's either a bug or a broken stream */
- result=best;
- while(result>vf->dataoffsets[link]){
- result=_get_prev_page(vf,result,&og);
- if(result<0) goto seek_error;
- if(ogg_page_serialno(&og)==vf->current_serialno &&
- (ogg_page_granulepos(&og)>-1 ||
- !ogg_page_continued(&og))){
- return ov_raw_seek(vf,result);
- }
- }
- }
- if(result<0){
- result = OV_EBADPACKET;
- goto seek_error;
- }
- if(op.granulepos!=-1){
- vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
- if(vf->pcm_offset<0)vf->pcm_offset=0;
- vf->pcm_offset+=total;
- break;
- }else
- result=ogg_stream_packetout(&vf->os,NULL);
+ result=tremor_ogg_stream_packetpeek(vf->os,&op);
+ if(result==0){
+ /* !!! the packet finishing this page originated on a
+ preceeding page. Keep fetching previous pages until we
+ get one with a granulepos or without the 'continued' flag
+ set. Then just use raw_seek for simplicity. */
+
+ _seek_helper(vf,best);
+
+ while(1){
+ result=_get_prev_page(vf,&og);
+ if(result<0) goto seek_error;
+ if(tremor_ogg_page_granulepos(&og)>-1 ||
+ !tremor_ogg_page_continued(&og)){
+ return ov_raw_seek(vf,result);
+ }
+ vf->offset=result;
+ }
+ }
+ if(result<0){
+ result = OV_EBADPACKET;
+ goto seek_error;
+ }
+ if(op.granulepos!=-1){
+ vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
+ if(vf->pcm_offset<0)vf->pcm_offset=0;
+ vf->pcm_offset+=total;
+ break;
+ }else
+ result=tremor_ogg_stream_packetout(vf->os,NULL);
}
}
}
-
+
/* verify result */
if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
result=OV_EFAULT;
@@ -1645,89 +1284,98 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
}
vf->bittrack=0;
vf->samptrack=0;
- return(0);
+ tremor_ogg_page_release(&og);
+ tremor_ogg_packet_release(&op);
+ return 0;
+
seek_error:
+
+ tremor_ogg_page_release(&og);
+ tremor_ogg_packet_release(&op);
+
/* dump machine so we're in a known state */
vf->pcm_offset=-1;
_decode_clear(vf);
return (int)result;
}
-/* seek to a sample offset relative to the decompressed pcm stream
+/* seek to a sample offset relative to the decompressed pcm stream
returns zero on success, nonzero on failure */
-int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
+int ov_pcm_seek(TremorOggVorbis_File *vf,tremor_ogg_int64_t pos){
+ tremor_ogg_packet op={0,0,0,0,0,0};
+ tremor_ogg_page og={0,0,0,0};
int thisblock,lastblock=0;
int ret=ov_pcm_seek_page(vf,pos);
- if(ret<0)return(ret);
- if((ret=_make_decode_ready(vf)))return ret;
+ if(ret<0)return ret;
+ if(_make_decode_ready(vf))return OV_EBADLINK;
/* discard leading packets we don't need for the lapping of the
position we want; don't decode them */
while(1){
- ogg_packet op;
- ogg_page og;
- int ret=ogg_stream_packetpeek(&vf->os,&op);
+ int ret=tremor_ogg_stream_packetpeek(vf->os,&op);
if(ret>0){
- thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
+ thisblock=vorbis_packet_blocksize(&vf->vi,&op);
if(thisblock<0){
- ogg_stream_packetout(&vf->os,NULL);
- continue; /* non audio packet */
+ tremor_ogg_stream_packetout(vf->os,NULL);
+ continue; /* non audio packet */
}
if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
-
+
if(vf->pcm_offset+((thisblock+
- vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
-
+ vorbis_info_blocksize(&vf->vi,1))>>2)>=pos)break;
+
/* remove the packet from packet queue and track its granulepos */
- ogg_stream_packetout(&vf->os,NULL);
- vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
- only tracking, no
- pcm_decode */
- vorbis_synthesis_blockin(&vf->vd,&vf->vb);
-
+ tremor_ogg_stream_packetout(vf->os,NULL);
+ vorbis_dsp_synthesis(vf->vd,&op,0); /* set up a vb with
+ only tracking, no
+ pcm_decode */
+
/* end of logical stream case is hard, especially with exact
- length positioning. */
-
+ length positioning. */
+
if(op.granulepos>-1){
- int i;
- /* always believe the stream markers */
- vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
- if(vf->pcm_offset<0)vf->pcm_offset=0;
- for(i=0;i<vf->current_link;i++)
- vf->pcm_offset+=vf->pcmlengths[i*2+1];
+ int i;
+ /* always believe the stream markers */
+ vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
+ if(vf->pcm_offset<0)vf->pcm_offset=0;
+ for(i=0;i<vf->current_link;i++)
+ vf->pcm_offset+=vf->pcmlengths[i*2+1];
}
-
+
lastblock=thisblock;
-
+
}else{
if(ret<0 && ret!=OV_HOLE)break;
-
+
/* suck in a new page */
if(_get_next_page(vf,&og,-1)<0)break;
- if(ogg_page_bos(&og))_decode_clear(vf);
-
+ if(vf->current_serialno!=tremor_ogg_page_serialno(&og))_decode_clear(vf);
+
if(vf->ready_state<STREAMSET){
- ogg_uint32_t serialno=ogg_page_serialno(&og);
- int link;
-
- for(link=0;link<vf->links;link++)
- if(vf->serialnos[link]==serialno)break;
- if(link==vf->links) continue;
- vf->current_link=link;
-
- vf->ready_state=STREAMSET;
- vf->current_serialno=ogg_page_serialno(&og);
- ogg_stream_reset_serialno(&vf->os,serialno);
- ret=_make_decode_ready(vf);
- if(ret)return ret;
- lastblock=0;
+ int link,ret;
+
+ vf->current_serialno=tremor_ogg_page_serialno(&og);
+ for(link=0;link<vf->links;link++)
+ if(vf->serialnos[link]==vf->current_serialno)break;
+ if(link==vf->links){
+ tremor_ogg_page_release(&og);
+ tremor_ogg_packet_release(&op);
+ return OV_EBADLINK;
+ }
+
+
+ vf->current_link=link;
+ ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
+ if(ret) return ret;
+ if(_make_decode_ready(vf))return OV_EBADLINK;
+ lastblock=0;
}
- ogg_stream_pagein(&vf->os,&og);
+ tremor_ogg_stream_pagein(vf->os,&og);
}
}
@@ -1736,104 +1384,107 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
/* discard samples until we reach the desired position. Crossing a
logical bitstream boundary with abandon is OK. */
while(vf->pcm_offset<pos){
- ogg_int64_t target=pos-vf->pcm_offset;
- long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
+ tremor_ogg_int64_t target=pos-vf->pcm_offset;
+ long samples=vorbis_dsp_pcmout(vf->vd,NULL,0);
if(samples>target)samples=target;
- vorbis_synthesis_read(&vf->vd,samples);
+ vorbis_dsp_read(vf->vd,samples);
vf->pcm_offset+=samples;
-
+
if(samples<target)
- if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
- vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
+ if(_fetch_and_process_packet(vf,1,1)<=0)
+ vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
}
+
+ tremor_ogg_page_release(&og);
+ tremor_ogg_packet_release(&op);
return 0;
}
-/* seek to a playback time relative to the decompressed pcm stream
+/* seek to a playback time relative to the decompressed pcm stream
returns zero on success, nonzero on failure */
-int ov_time_seek(OggVorbis_File *vf,ogg_int64_t milliseconds){
+int ov_time_seek(TremorOggVorbis_File *vf,tremor_ogg_int64_t milliseconds){
/* translate time to PCM position and call ov_pcm_seek */
int link=-1;
- ogg_int64_t pcm_total=0;
- ogg_int64_t time_total=0;
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable)return(OV_ENOSEEK);
- if(milliseconds<0)return(OV_EINVAL);
+ tremor_ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
+ tremor_ogg_int64_t time_total=ov_time_total(vf,-1);
+ if(vf->ready_state<OPENED)return OV_EINVAL;
+ if(!vf->seekable)return OV_ENOSEEK;
+ if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL;
+
/* which bitstream section does this time offset occur in? */
- for(link=0;link<vf->links;link++){
- ogg_int64_t addsec = ov_time_total(vf,link);
- if(milliseconds<time_total+addsec)break;
- time_total+=addsec;
- pcm_total+=vf->pcmlengths[link*2+1];
+ for(link=vf->links-1;link>=0;link--){
+ pcm_total-=vf->pcmlengths[link*2+1];
+ time_total-=ov_time_total(vf,link);
+ if(milliseconds>=time_total)break;
}
- if(link==vf->links)return(OV_EINVAL);
-
/* enough information to convert time offset to pcm offset */
{
- ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000;
- return(ov_pcm_seek(vf,target));
+ int ret=_set_link_number(vf,link);
+ if(ret)return ret;
+ return
+ ov_pcm_seek(vf,pcm_total+(milliseconds-time_total)*
+ vf->vi.rate/1000);
}
}
/* page-granularity version of ov_time_seek
returns zero on success, nonzero on failure */
-int ov_time_seek_page(OggVorbis_File *vf,ogg_int64_t milliseconds){
+int ov_time_seek_page(TremorOggVorbis_File *vf,tremor_ogg_int64_t milliseconds){
/* translate time to PCM position and call ov_pcm_seek */
int link=-1;
- ogg_int64_t pcm_total=0;
- ogg_int64_t time_total=0;
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- if(!vf->seekable)return(OV_ENOSEEK);
- if(milliseconds<0)return(OV_EINVAL);
+ tremor_ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
+ tremor_ogg_int64_t time_total=ov_time_total(vf,-1);
+ if(vf->ready_state<OPENED)return OV_EINVAL;
+ if(!vf->seekable)return OV_ENOSEEK;
+ if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL;
+
/* which bitstream section does this time offset occur in? */
- for(link=0;link<vf->links;link++){
- ogg_int64_t addsec = ov_time_total(vf,link);
- if(milliseconds<time_total+addsec)break;
- time_total+=addsec;
- pcm_total+=vf->pcmlengths[link*2+1];
+ for(link=vf->links-1;link>=0;link--){
+ pcm_total-=vf->pcmlengths[link*2+1];
+ time_total-=ov_time_total(vf,link);
+ if(milliseconds>=time_total)break;
}
- if(link==vf->links)return(OV_EINVAL);
-
/* enough information to convert time offset to pcm offset */
{
- ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000;
- return(ov_pcm_seek_page(vf,target));
+ int ret=_set_link_number(vf,link);
+ if(ret)return ret;
+ return
+ ov_pcm_seek_page(vf,pcm_total+(milliseconds-time_total)*
+ vf->vi.rate/1000);
}
}
/* tell the current stream offset cursor. Note that seek followed by
tell will likely not give the set offset due to caching */
-ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- return(vf->offset);
+tremor_ogg_int64_t ov_raw_tell(TremorOggVorbis_File *vf){
+ if(vf->ready_state<OPENED)return OV_EINVAL;
+ return vf->offset;
}
/* return PCM offset (sample) of next PCM sample to be read */
-ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
- if(vf->ready_state<OPENED)return(OV_EINVAL);
- return(vf->pcm_offset);
+tremor_ogg_int64_t ov_pcm_tell(TremorOggVorbis_File *vf){
+ if(vf->ready_state<OPENED)return OV_EINVAL;
+ return vf->pcm_offset;
}
/* return time offset (milliseconds) of next PCM sample to be read */
-ogg_int64_t ov_time_tell(OggVorbis_File *vf){
+tremor_ogg_int64_t ov_time_tell(TremorOggVorbis_File *vf){
int link=0;
- ogg_int64_t pcm_total=0;
- ogg_int64_t time_total=0;
-
- if(vf->ready_state<OPENED)return(OV_EINVAL);
+ tremor_ogg_int64_t pcm_total=0;
+ tremor_ogg_int64_t time_total=0;
+
+ if(vf->ready_state<OPENED)return OV_EINVAL;
if(vf->seekable){
pcm_total=ov_pcm_total(vf,-1);
time_total=ov_time_total(vf,-1);
-
+
/* which bitstream section does this time offset occur in? */
for(link=vf->links-1;link>=0;link--){
pcm_total-=vf->pcmlengths[link*2+1];
@@ -1842,50 +1493,38 @@ ogg_int64_t ov_time_tell(OggVorbis_File *vf){
}
}
- return(time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi[link].rate);
+ return time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi.rate;
}
/* link: -1) return the vorbis_info struct for the bitstream section
currently being decoded
0-n) to request information for a specific bitstream section
-
+
In the case of a non-seekable bitstream, any call returns the
current bitstream. NULL in the case that the machine is not
initialized */
-vorbis_info *ov_info(OggVorbis_File *vf,int link){
+vorbis_info *ov_info(TremorOggVorbis_File *vf,int link){
if(vf->seekable){
- if(link<0)
- if(vf->ready_state>=STREAMSET)
- return vf->vi+vf->current_link;
- else
- return vf->vi;
- else
- if(link>=vf->links)
- return NULL;
- else
- return vf->vi+link;
- }else{
- return vf->vi;
+ if(link>=vf->links)return NULL;
+ if(link>=0){
+ int ret=_set_link_number_preserve_pos(vf,link);
+ if(ret)return NULL;
+ }
}
+ return &vf->vi;
}
/* grr, strong typing, grr, no templates/inheritence, grr */
-vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
+vorbis_comment *ov_comment(TremorOggVorbis_File *vf,int link){
if(vf->seekable){
- if(link<0)
- if(vf->ready_state>=STREAMSET)
- return vf->vc+vf->current_link;
- else
- return vf->vc;
- else
- if(link>=vf->links)
- return NULL;
- else
- return vf->vc+link;
- }else{
- return vf->vc;
+ if(link>=vf->links)return NULL;
+ if(link>=0){
+ int ret=_set_link_number_preserve_pos(vf,link);
+ if(ret)return NULL;
+ }
}
+ return &vf->vc;
}
/* up to this point, everything could more or less hide the multiple
@@ -1904,65 +1543,47 @@ vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
functions above are aware of this dichotomy).
input values: buffer) a buffer to hold packed PCM data for return
- bytes_req) the byte length requested to be placed into buffer
+ length) the byte length requested to be placed into buffer
return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
0) EOF
- n) number of bytes of PCM actually returned. The
- below works on a packet-by-packet basis, so the
- return length is not related to the 'length' passed
- in, just guaranteed to fit.
+ n) number of bytes of PCM actually returned. The
+ below works on a packet-by-packet basis, so the
+ return length is not related to the 'length' passed
+ in, just guaranteed to fit.
- *section) set to the logical bitstream number */
+ *section) set to the logical bitstream number */
-long ov_read(OggVorbis_File *vf,char *buffer,int bytes_req,int *bitstream){
- int i,j;
+long ov_read(TremorOggVorbis_File *vf,void *buffer,int bytes_req,int *bitstream){
- ogg_int32_t **pcm;
long samples;
+ long channels;
- if(vf->ready_state<OPENED)return(OV_EINVAL);
+ if(vf->ready_state<OPENED)return OV_EINVAL;
while(1){
if(vf->ready_state==INITSET){
- samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
- if(samples)break;
+ channels=vf->vi.channels;
+ samples=vorbis_dsp_pcmout(vf->vd,buffer,(bytes_req>>1)/channels);
+ if(samples){
+ if(samples>0){
+ vorbis_dsp_read(vf->vd,samples);
+ vf->pcm_offset+=samples;
+ if(bitstream)*bitstream=vf->current_link;
+ return samples*2*channels;
+ }
+ return samples;
+ }
}
/* suck in another packet */
{
- int ret=_fetch_and_process_packet(vf,NULL,1,1);
+ int ret=_fetch_and_process_packet(vf,1,1);
if(ret==OV_EOF)
- return(0);
+ return 0;
if(ret<=0)
- return(ret);
+ return ret;
}
}
-
- if(samples>0){
-
- /* yay! proceed to pack data into the byte buffer */
-
- long channels=ov_info(vf,-1)->channels;
-
- if(samples>(bytes_req/(2*channels)))
- samples=bytes_req/(2*channels);
-
- for(i=0;i<channels;i++) { /* It's faster in this order */
- ogg_int32_t *src=pcm[i];
- short *dest=((short *)buffer)+i;
- for(j=0;j<samples;j++) {
- *dest=CLIP_TO_15(src[j]>>9);
- dest+=channels;
- }
- }
-
- vorbis_synthesis_read(&vf->vd,samples);
- vf->pcm_offset+=samples;
- if(bitstream)*bitstream=vf->current_link;
- return(samples*2*channels);
- }else{
- return(samples);
- }
}
diff --git a/lib/tremor/vorbisidec.pc.in b/lib/tremor/vorbisidec.pc.in
index 56fa6567..9c095242 100644
--- a/lib/tremor/vorbisidec.pc.in
+++ b/lib/tremor/vorbisidec.pc.in
@@ -8,7 +8,7 @@ includedir=@includedir@
Name: vorbisidec
Description: vorbisidec is the integer Ogg Vorbis library
Version: @VERSION@
-Requires.private: ogg
+Requires: ogg
Conflicts:
-Libs: -L${libdir} -lvorbisidec
+Libs: -L${libdir} -lvorbisidec -lm
Cflags: -I${includedir}
diff --git a/lib/tremor/win32/VS2005/libogg.vsprops b/lib/tremor/win32/VS2005/libogg.vsprops
deleted file mode 100644
index dca12081..00000000
--- a/lib/tremor/win32/VS2005/libogg.vsprops
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="windows-1250"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="libogg"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;..\..\..\..\libogg-$(LIBOGG_VERSION)\include&quot;;..\..\..\..\ogg\include;..\..\..\..\..\..\..\core\ogg\libogg\include"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalLibraryDirectories="&quot;..\..\..\..\libogg-$(LIBOGG_VERSION)\win32\VS2005\$(PlatformName)\$(ConfigurationName)&quot;;&quot;..\..\..\..\ogg\win32\VS2005\$(PlatformName)\$(ConfigurationName)&quot;;&quot;..\..\..\..\..\..\..\core\ogg\libogg\win32\VS2005\$(PlatformName)\$(ConfigurationName)&quot;"
- />
- <UserMacro
- Name="LIBOGG_VERSION"
- Value="1.1.4"
- />
-</VisualStudioPropertySheet>
diff --git a/lib/tremor/win32/VS2005/libtremor/libtremor.vcproj b/lib/tremor/win32/VS2005/libtremor/libtremor.vcproj
deleted file mode 100644
index c18654f6..00000000
--- a/lib/tremor/win32/VS2005/libtremor/libtremor.vcproj
+++ /dev/null
@@ -1,865 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8,00"
- Name="libtremor"
- ProjectGUID="{7A8E774E-DD94-43B8-8758-6F9F656CC8D2}"
- RootNamespace="libtremor"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- <Platform
- Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- />
- <Platform
- Name="Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- />
- <Platform
- Name="Windows Mobile 6 Professional SDK (ARMV4I)"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="_DEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- MinimalRebuild="true"
- RuntimeLibrary="1"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- <Configuration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="_DEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- MinimalRebuild="true"
- RuntimeLibrary="1"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- <Configuration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="_DEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- MinimalRebuild="true"
- RuntimeLibrary="1"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="NDEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- RuntimeLibrary="0"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- <Configuration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="NDEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- RuntimeLibrary="0"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- <Configuration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="NDEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- RuntimeLibrary="0"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\..\block.c"
- >
- </File>
- <File
- RelativePath="..\..\..\codebook.c"
- >
- </File>
- <File
- RelativePath="..\..\..\floor0.c"
- >
- </File>
- <File
- RelativePath="..\..\..\floor1.c"
- >
- </File>
- <File
- RelativePath="..\..\..\info.c"
- >
- </File>
- <File
- RelativePath="..\..\..\mapping0.c"
- >
- </File>
- <File
- RelativePath="..\..\..\mdct.c"
- >
- </File>
- <File
- RelativePath="..\..\..\registry.c"
- >
- </File>
- <File
- RelativePath="..\..\..\res012.c"
- >
- </File>
- <File
- RelativePath="..\..\..\sharedbook.c"
- >
- </File>
- <File
- RelativePath="..\..\..\synthesis.c"
- >
- </File>
- <File
- RelativePath="..\..\..\window.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\..\backends.h"
- >
- </File>
- <File
- RelativePath="..\..\..\block.h"
- >
- </File>
- <File
- RelativePath="..\..\..\codebook.h"
- >
- </File>
- <File
- RelativePath="..\..\..\codec_internal.h"
- >
- </File>
- <File
- RelativePath="..\..\..\config_types.h"
- >
- </File>
- <File
- RelativePath="..\..\..\ivorbiscodec.h"
- >
- </File>
- <File
- RelativePath="..\..\..\ivorbisfile.h"
- >
- </File>
- <File
- RelativePath="..\..\..\lsp_lookup.h"
- >
- </File>
- <File
- RelativePath="..\..\..\mdct.h"
- >
- </File>
- <File
- RelativePath="..\..\..\mdct_lookup.h"
- >
- </File>
- <File
- RelativePath="..\..\..\misc.h"
- >
- </File>
- <File
- RelativePath="..\..\..\ogg.h"
- >
- </File>
- <File
- RelativePath="..\..\..\os.h"
- >
- </File>
- <File
- RelativePath="..\..\..\os_types.h"
- >
- </File>
- <File
- RelativePath="..\..\..\registry.h"
- >
- </File>
- <File
- RelativePath="..\..\..\window.h"
- >
- </File>
- <File
- RelativePath="..\..\..\window_lookup.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <File
- RelativePath=".\ReadMe.txt"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/lib/tremor/win32/VS2008/libogg.vsprops b/lib/tremor/win32/VS2008/libogg.vsprops
deleted file mode 100644
index 807b74a6..00000000
--- a/lib/tremor/win32/VS2008/libogg.vsprops
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="windows-1250"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="libogg"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;..\..\..\..\libogg-$(LIBOGG_VERSION)\include&quot;;..\..\..\..\ogg\include;..\..\..\..\..\..\..\core\ogg\libogg\include"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalLibraryDirectories="&quot;..\..\..\..\libogg-$(LIBOGG_VERSION)\win32\VS2008\$(PlatformName)\$(ConfigurationName)&quot;;&quot;..\..\..\..\ogg\win32\VS2008\$(PlatformName)\$(ConfigurationName)&quot;;&quot;..\..\..\..\..\..\..\core\ogg\libogg\win32\VS2008\$(PlatformName)\$(ConfigurationName)&quot;"
- />
- <UserMacro
- Name="LIBOGG_VERSION"
- Value="1.1.4"
- />
-</VisualStudioPropertySheet>
diff --git a/lib/tremor/win32/VS2008/libtremor/libtremor.vcproj b/lib/tremor/win32/VS2008/libtremor/libtremor.vcproj
deleted file mode 100644
index 7edb39b9..00000000
--- a/lib/tremor/win32/VS2008/libtremor/libtremor.vcproj
+++ /dev/null
@@ -1,865 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="9,00"
- Name="libtremor"
- ProjectGUID="{7A8E774E-DD94-43B8-8758-6F9F656CC8D2}"
- RootNamespace="libtremor"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- <Platform
- Name="Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- />
- <Platform
- Name="Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- />
- <Platform
- Name="Windows Mobile 6 Professional SDK (ARMV4I)"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="_DEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- MinimalRebuild="true"
- RuntimeLibrary="1"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- <Configuration
- Name="Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="_DEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- MinimalRebuild="true"
- RuntimeLibrary="1"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- <Configuration
- Name="Debug|Windows Mobile 6 Professional SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="_DEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- MinimalRebuild="true"
- RuntimeLibrary="1"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="NDEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- RuntimeLibrary="0"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- <Configuration
- Name="Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="NDEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- RuntimeLibrary="0"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- <Configuration
- Name="Release|Windows Mobile 6 Professional SDK (ARMV4I)"
- OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
- ConfigurationType="4"
- InheritedPropertySheets="..\libogg.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="1"
- />
- <Tool
- Name="VCCLCompilerTool"
- ExecutionBucket="7"
- AdditionalIncludeDirectories="..\..\..\include;..\..\..\..\libogg\include"
- PreprocessorDefinitions="NDEBUG;_LIB;_WIN32_WCE=$(CEVER);UNDER_CE;WIN32;WINCE;$(ARCHFAM);$(_ARCHFAM_);$(PLATFORMDEFINES)"
- RuntimeLibrary="0"
- TreatWChar_tAsBuiltInType="false"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCCodeSignTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- <DeploymentTool
- ForceDirty="-1"
- RemoteDirectory=""
- RegisterOutput="0"
- AdditionalFiles=""
- />
- <DebuggerTool
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath="..\..\..\block.c"
- >
- </File>
- <File
- RelativePath="..\..\..\codebook.c"
- >
- </File>
- <File
- RelativePath="..\..\..\floor0.c"
- >
- </File>
- <File
- RelativePath="..\..\..\floor1.c"
- >
- </File>
- <File
- RelativePath="..\..\..\info.c"
- >
- </File>
- <File
- RelativePath="..\..\..\mapping0.c"
- >
- </File>
- <File
- RelativePath="..\..\..\mdct.c"
- >
- </File>
- <File
- RelativePath="..\..\..\registry.c"
- >
- </File>
- <File
- RelativePath="..\..\..\res012.c"
- >
- </File>
- <File
- RelativePath="..\..\..\sharedbook.c"
- >
- </File>
- <File
- RelativePath="..\..\..\synthesis.c"
- >
- </File>
- <File
- RelativePath="..\..\..\window.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath="..\..\..\backends.h"
- >
- </File>
- <File
- RelativePath="..\..\..\block.h"
- >
- </File>
- <File
- RelativePath="..\..\..\codebook.h"
- >
- </File>
- <File
- RelativePath="..\..\..\codec_internal.h"
- >
- </File>
- <File
- RelativePath="..\..\..\config_types.h"
- >
- </File>
- <File
- RelativePath="..\..\..\ivorbiscodec.h"
- >
- </File>
- <File
- RelativePath="..\..\..\ivorbisfile.h"
- >
- </File>
- <File
- RelativePath="..\..\..\lsp_lookup.h"
- >
- </File>
- <File
- RelativePath="..\..\..\mdct.h"
- >
- </File>
- <File
- RelativePath="..\..\..\mdct_lookup.h"
- >
- </File>
- <File
- RelativePath="..\..\..\misc.h"
- >
- </File>
- <File
- RelativePath="..\..\..\ogg.h"
- >
- </File>
- <File
- RelativePath="..\..\..\os.h"
- >
- </File>
- <File
- RelativePath="..\..\..\os_types.h"
- >
- </File>
- <File
- RelativePath="..\..\..\registry.h"
- >
- </File>
- <File
- RelativePath="..\..\..\window.h"
- >
- </File>
- <File
- RelativePath="..\..\..\window_lookup.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <File
- RelativePath=".\ReadMe.txt"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/lib/tremor/window.c b/lib/tremor/window.c
deleted file mode 100644
index 006a1ee6..00000000
--- a/lib/tremor/window.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
- * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: window functions
-
- ********************************************************************/
-
-#include <stdlib.h>
-#include <math.h>
-#include "misc.h"
-#include "window.h"
-#include "window_lookup.h"
-
-const void *_vorbis_window(int type, int left){
-
- switch(type){
- case 0:
-
- switch(left){
- case 32:
- return vwin64;
- case 64:
- return vwin128;
- case 128:
- return vwin256;
- case 256:
- return vwin512;
- case 512:
- return vwin1024;
- case 1024:
- return vwin2048;
- case 2048:
- return vwin4096;
- case 4096:
- return vwin8192;
- default:
- return(0);
- }
- break;
- default:
- return(0);
- }
-}
-
-void _vorbis_apply_window(ogg_int32_t *d,const void *window_p[2],
- long *blocksizes,
- int lW,int W,int nW){
-
- LOOKUP_T *window[2]={window_p[0],window_p[1]};
- long n=blocksizes[W];
- long ln=blocksizes[lW];
- long rn=blocksizes[nW];
-
- long leftbegin=n/4-ln/4;
- long leftend=leftbegin+ln/2;
-
- long rightbegin=n/2+n/4-rn/4;
- long rightend=rightbegin+rn/2;
-
- int i,p;
-
- for(i=0;i<leftbegin;i++)
- d[i]=0;
-
- for(p=0;i<leftend;i++,p++)
- d[i]=MULT31(d[i],window[lW][p]);
-
- for(i=rightbegin,p=rn/2-1;i<rightend;i++,p--)
- d[i]=MULT31(d[i],window[nW][p]);
-
- for(;i<n;i++)
- d[i]=0;
-}
diff --git a/lib/tremor/window.h b/lib/tremor/window.h
deleted file mode 100644
index 27647fe6..00000000
--- a/lib/tremor/window.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
- * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: window functions
-
- ********************************************************************/
-
-#ifndef _V_WINDOW_
-#define _V_WINDOW_
-
-extern const void *_vorbis_window(int type,int left);
-extern void _vorbis_apply_window(ogg_int32_t *d,const void *window[2],
- long *blocksizes,
- int lW,int W,int nW);
-
-
-#endif
diff --git a/lib/tremor/window_lookup.h b/lib/tremor/window_lookup.h
index fc0494e6..d2e69371 100644
--- a/lib/tremor/window_lookup.h
+++ b/lib/tremor/window_lookup.h
@@ -1,12 +1,12 @@
/********************************************************************
* *
- * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * THIS FILE IS PART OF THE TremorOggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * THE TremorOggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
@@ -16,9 +16,9 @@
********************************************************************/
-#include <ogg/os_types.h>
+#include "os_types.h"
-static const LOOKUP_T vwin64[32] = {
+static LOOKUP_T vwin64[32] = {
X(0x001f0003), X(0x01168c98), X(0x030333c8), X(0x05dfe3a4),
X(0x09a49562), X(0x0e45df18), X(0x13b47ef2), X(0x19dcf676),
X(0x20a74d83), X(0x27f7137c), X(0x2fabb05a), X(0x37a1105a),
@@ -29,7 +29,7 @@ static const LOOKUP_T vwin64[32] = {
X(0x7fdd78a5), X(0x7ff6ec6d), X(0x7ffed0e9), X(0x7ffffc3f),
};
-static const LOOKUP_T vwin128[64] = {
+static LOOKUP_T vwin128[64] = {
X(0x0007c04d), X(0x0045bb89), X(0x00c18b87), X(0x017ae294),
X(0x02714a4e), X(0x03a4217a), X(0x05129952), X(0x06bbb24f),
X(0x089e38a1), X(0x0ab8c073), X(0x0d09a228), X(0x0f8ef6bd),
@@ -48,7 +48,7 @@ static const LOOKUP_T vwin128[64] = {
X(0x7ffdcf39), X(0x7fff6dac), X(0x7fffed01), X(0x7fffffc4),
};
-static const LOOKUP_T vwin256[128] = {
+static LOOKUP_T vwin256[128] = {
X(0x0001f018), X(0x00117066), X(0x00306e9e), X(0x005ee5f1),
X(0x009ccf26), X(0x00ea208b), X(0x0146cdea), X(0x01b2c87f),
X(0x022dfedf), X(0x02b85ced), X(0x0351cbbd), X(0x03fa317f),
@@ -83,7 +83,7 @@ static const LOOKUP_T vwin256[128] = {
X(0x7fffdcd2), X(0x7ffff6d6), X(0x7ffffed0), X(0x7ffffffc),
};
-static const LOOKUP_T vwin512[256] = {
+static LOOKUP_T vwin512[256] = {
X(0x00007c06), X(0x00045c32), X(0x000c1c62), X(0x0017bc4c),
X(0x00273b7a), X(0x003a9955), X(0x0051d51c), X(0x006cede7),
X(0x008be2a9), X(0x00aeb22a), X(0x00d55b0d), X(0x00ffdbcc),
@@ -150,7 +150,7 @@ static const LOOKUP_T vwin512[256] = {
X(0x7ffffdcd), X(0x7fffff6d), X(0x7fffffed), X(0x7fffffff),
};
-static const LOOKUP_T vwin1024[512] = {
+static LOOKUP_T vwin1024[512] = {
X(0x00001f02), X(0x0001170e), X(0x00030724), X(0x0005ef40),
X(0x0009cf59), X(0x000ea767), X(0x0014775e), X(0x001b3f2e),
X(0x0022fec8), X(0x002bb618), X(0x00356508), X(0x00400b81),
@@ -281,7 +281,7 @@ static const LOOKUP_T vwin1024[512] = {
X(0x7fffffdd), X(0x7ffffff7), X(0x7fffffff), X(0x7fffffff),
};
-static const LOOKUP_T vwin2048[1024] = {
+static LOOKUP_T vwin2048[1024] = {
X(0x000007c0), X(0x000045c4), X(0x0000c1ca), X(0x00017bd3),
X(0x000273de), X(0x0003a9eb), X(0x00051df9), X(0x0006d007),
X(0x0008c014), X(0x000aee1e), X(0x000d5a25), X(0x00100428),
@@ -540,7 +540,7 @@ static const LOOKUP_T vwin2048[1024] = {
X(0x7ffffffe), X(0x7fffffff), X(0x7fffffff), X(0x7fffffff),
};
-static const LOOKUP_T vwin4096[2048] = {
+static LOOKUP_T vwin4096[2048] = {
X(0x000001f0), X(0x00001171), X(0x00003072), X(0x00005ef5),
X(0x00009cf8), X(0x0000ea7c), X(0x00014780), X(0x0001b405),
X(0x0002300b), X(0x0002bb91), X(0x00035698), X(0x0004011e),
@@ -1055,7 +1055,9 @@ static const LOOKUP_T vwin4096[2048] = {
X(0x7fffffff), X(0x7fffffff), X(0x7fffffff), X(0x7fffffff),
};
-static const LOOKUP_T vwin8192[4096] = {
+#ifndef LIMIT_TO_64kHz
+
+static LOOKUP_T vwin8192[4096] = {
X(0x0000007c), X(0x0000045c), X(0x00000c1d), X(0x000017bd),
X(0x0000273e), X(0x00003a9f), X(0x000051e0), X(0x00006d02),
X(0x00008c03), X(0x0000aee5), X(0x0000d5a7), X(0x00010049),
@@ -2082,3 +2084,4 @@ static const LOOKUP_T vwin8192[4096] = {
X(0x7fffffff), X(0x7fffffff), X(0x7fffffff), X(0x7fffffff),
};
+#endif