# HG changeset patch # User koda # Date 1351393207 -3600 # Node ID a12155461b34bdf6d60f0c73021f750af9e84bd8 # Parent 775a72905708f1fc58841f91748b97d001b30fc6 revert r767d3c4153a1 this tremor implementation is buggy diff -r 775a72905708 -r a12155461b34 misc/libtremor/Android.mk --- a/misc/libtremor/Android.mk Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/Android.mk Sun Oct 28 04:00:07 2012 +0100 @@ -7,12 +7,21 @@ LOCAL_CFLAGS := -I$(LOCAL_PATH) -DHAVE_ALLOCA_H LOCAL_SRC_FILES = \ - tremor/bitwise.c tremor/info.c tremor/codebook.c \ - tremor/dsp.c tremor/mapping0.c \ - tremor/floor0.c tremor/mdct.c \ - tremor/floor1.c tremor/misc.c \ - tremor/floor_lookup.c tremor/res012.c \ - tremor/framing.c tremor/vorbisfile.c + tremor/bitwise.c \ + tremor/block.c \ + tremor/codebook.c \ + tremor/floor0.c \ + tremor/floor1.c \ + tremor/framing.c \ + tremor/info.c \ + tremor/mapping0.c \ + tremor/mdct.c \ + tremor/registry.c \ + tremor/res012.c \ + tremor/sharedbook.c \ + tremor/synthesis.c \ + tremor/vorbisfile.c \ + tremor/window.c include $(BUILD_STATIC_LIBRARY) diff -r 775a72905708 -r a12155461b34 misc/libtremor/Xcode/Tremor.xcodeproj/project.pbxproj --- a/misc/libtremor/Xcode/Tremor.xcodeproj/project.pbxproj Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/Xcode/Tremor.xcodeproj/project.pbxproj Sun Oct 28 04:00:07 2012 +0100 @@ -8,7 +8,10 @@ /* Begin PBXBuildFile section */ 61DB1809148BA9A9004A67B8 /* asm_arm.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17E7148BA9A9004A67B8 /* asm_arm.h */; }; + 61DB180A148BA9A9004A67B8 /* backends.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17E8148BA9A9004A67B8 /* backends.h */; }; 61DB180B148BA9A9004A67B8 /* bitwise.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17E9148BA9A9004A67B8 /* bitwise.c */; }; + 61DB180C148BA9A9004A67B8 /* block.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17EA148BA9A9004A67B8 /* block.c */; }; + 61DB180D148BA9A9004A67B8 /* block.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17EB148BA9A9004A67B8 /* block.h */; }; 61DB180E148BA9A9004A67B8 /* codebook.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB17EC148BA9A9004A67B8 /* codebook.c */; }; 61DB180F148BA9A9004A67B8 /* codebook.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17ED148BA9A9004A67B8 /* codebook.h */; }; 61DB1810148BA9A9004A67B8 /* codec_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17EE148BA9A9004A67B8 /* codec_internal.h */; }; @@ -28,19 +31,25 @@ 61DB181F148BA9A9004A67B8 /* ogg.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17FD148BA9A9004A67B8 /* ogg.h */; }; 61DB1820148BA9A9004A67B8 /* os_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17FE148BA9A9004A67B8 /* os_types.h */; }; 61DB1821148BA9A9004A67B8 /* os.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB17FF148BA9A9004A67B8 /* os.h */; }; + 61DB1822148BA9A9004A67B8 /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1800148BA9A9004A67B8 /* registry.c */; }; + 61DB1823148BA9A9004A67B8 /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB1801148BA9A9004A67B8 /* registry.h */; }; 61DB1824148BA9A9004A67B8 /* res012.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1802148BA9A9004A67B8 /* res012.c */; }; + 61DB1825148BA9A9004A67B8 /* sharedbook.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1803148BA9A9004A67B8 /* sharedbook.c */; }; + 61DB1826148BA9A9004A67B8 /* synthesis.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1804148BA9A9004A67B8 /* synthesis.c */; }; 61DB1827148BA9A9004A67B8 /* vorbisfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1805148BA9A9004A67B8 /* vorbisfile.c */; }; 61DB1828148BA9A9004A67B8 /* window_lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB1806148BA9A9004A67B8 /* window_lookup.h */; }; - 61E1A173160BCA4F002370D0 /* dsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 61E1A170160BCA4F002370D0 /* dsp.c */; }; - 61E1A174160BCA4F002370D0 /* floor_lookup.c in Sources */ = {isa = PBXBuildFile; fileRef = 61E1A171160BCA4F002370D0 /* floor_lookup.c */; }; - 61E1A175160BCA4F002370D0 /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 61E1A172160BCA4F002370D0 /* misc.c */; }; + 61DB1829148BA9A9004A67B8 /* window.c in Sources */ = {isa = PBXBuildFile; fileRef = 61DB1807148BA9A9004A67B8 /* window.c */; }; + 61DB182A148BA9A9004A67B8 /* window.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DB1808148BA9A9004A67B8 /* window.h */; }; AA747D9F0F9514B9006C5449 /* Tremor_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* Tremor_Prefix.pch */; }; AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 61DB17E7148BA9A9004A67B8 /* asm_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asm_arm.h; path = ../tremor/asm_arm.h; sourceTree = SOURCE_ROOT; }; + 61DB17E8148BA9A9004A67B8 /* backends.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = backends.h; path = ../tremor/backends.h; sourceTree = SOURCE_ROOT; }; 61DB17E9148BA9A9004A67B8 /* bitwise.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bitwise.c; path = ../tremor/bitwise.c; sourceTree = SOURCE_ROOT; }; + 61DB17EA148BA9A9004A67B8 /* block.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = block.c; path = ../tremor/block.c; sourceTree = SOURCE_ROOT; }; + 61DB17EB148BA9A9004A67B8 /* block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = block.h; path = ../tremor/block.h; sourceTree = SOURCE_ROOT; }; 61DB17EC148BA9A9004A67B8 /* codebook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = codebook.c; path = ../tremor/codebook.c; sourceTree = SOURCE_ROOT; }; 61DB17ED148BA9A9004A67B8 /* codebook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codebook.h; path = ../tremor/codebook.h; sourceTree = SOURCE_ROOT; }; 61DB17EE148BA9A9004A67B8 /* codec_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codec_internal.h; path = ../tremor/codec_internal.h; sourceTree = SOURCE_ROOT; }; @@ -60,12 +69,15 @@ 61DB17FD148BA9A9004A67B8 /* ogg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ogg.h; path = ../tremor/ogg.h; sourceTree = SOURCE_ROOT; }; 61DB17FE148BA9A9004A67B8 /* os_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = os_types.h; path = ../tremor/os_types.h; sourceTree = SOURCE_ROOT; }; 61DB17FF148BA9A9004A67B8 /* os.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = os.h; path = ../tremor/os.h; sourceTree = SOURCE_ROOT; }; + 61DB1800148BA9A9004A67B8 /* registry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = registry.c; path = ../tremor/registry.c; sourceTree = SOURCE_ROOT; }; + 61DB1801148BA9A9004A67B8 /* registry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = registry.h; path = ../tremor/registry.h; sourceTree = SOURCE_ROOT; }; 61DB1802148BA9A9004A67B8 /* res012.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = res012.c; path = ../tremor/res012.c; sourceTree = SOURCE_ROOT; }; + 61DB1803148BA9A9004A67B8 /* sharedbook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sharedbook.c; path = ../tremor/sharedbook.c; sourceTree = SOURCE_ROOT; }; + 61DB1804148BA9A9004A67B8 /* synthesis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = synthesis.c; path = ../tremor/synthesis.c; sourceTree = SOURCE_ROOT; }; 61DB1805148BA9A9004A67B8 /* vorbisfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vorbisfile.c; path = ../tremor/vorbisfile.c; sourceTree = SOURCE_ROOT; }; 61DB1806148BA9A9004A67B8 /* window_lookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = window_lookup.h; path = ../tremor/window_lookup.h; sourceTree = SOURCE_ROOT; }; - 61E1A170160BCA4F002370D0 /* dsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dsp.c; path = ../tremor/dsp.c; sourceTree = SOURCE_ROOT; }; - 61E1A171160BCA4F002370D0 /* floor_lookup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = floor_lookup.c; path = ../tremor/floor_lookup.c; sourceTree = SOURCE_ROOT; }; - 61E1A172160BCA4F002370D0 /* misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = misc.c; path = ../tremor/misc.c; sourceTree = SOURCE_ROOT; }; + 61DB1807148BA9A9004A67B8 /* window.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = window.c; path = ../tremor/window.c; sourceTree = SOURCE_ROOT; }; + 61DB1808148BA9A9004A67B8 /* window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = window.h; path = ../tremor/window.h; sourceTree = SOURCE_ROOT; }; AA747D9E0F9514B9006C5449 /* Tremor_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tremor_Prefix.pch; sourceTree = SOURCE_ROOT; }; AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; D2AAC07E0554694100DB518D /* libTremor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTremor.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -113,11 +125,11 @@ 08FB77AEFE84172EC02AAC07 /* Sources */ = { isa = PBXGroup; children = ( - 61E1A170160BCA4F002370D0 /* dsp.c */, - 61E1A171160BCA4F002370D0 /* floor_lookup.c */, - 61E1A172160BCA4F002370D0 /* misc.c */, 61DB17E7148BA9A9004A67B8 /* asm_arm.h */, + 61DB17E8148BA9A9004A67B8 /* backends.h */, 61DB17E9148BA9A9004A67B8 /* bitwise.c */, + 61DB17EA148BA9A9004A67B8 /* block.c */, + 61DB17EB148BA9A9004A67B8 /* block.h */, 61DB17EC148BA9A9004A67B8 /* codebook.c */, 61DB17ED148BA9A9004A67B8 /* codebook.h */, 61DB17EE148BA9A9004A67B8 /* codec_internal.h */, @@ -137,9 +149,15 @@ 61DB17FD148BA9A9004A67B8 /* ogg.h */, 61DB17FE148BA9A9004A67B8 /* os_types.h */, 61DB17FF148BA9A9004A67B8 /* os.h */, + 61DB1800148BA9A9004A67B8 /* registry.c */, + 61DB1801148BA9A9004A67B8 /* registry.h */, 61DB1802148BA9A9004A67B8 /* res012.c */, + 61DB1803148BA9A9004A67B8 /* sharedbook.c */, + 61DB1804148BA9A9004A67B8 /* synthesis.c */, 61DB1805148BA9A9004A67B8 /* vorbisfile.c */, 61DB1806148BA9A9004A67B8 /* window_lookup.h */, + 61DB1807148BA9A9004A67B8 /* window.c */, + 61DB1808148BA9A9004A67B8 /* window.h */, ); name = Sources; sourceTree = ""; @@ -161,6 +179,8 @@ files = ( AA747D9F0F9514B9006C5449 /* Tremor_Prefix.pch in Headers */, 61DB1809148BA9A9004A67B8 /* asm_arm.h in Headers */, + 61DB180A148BA9A9004A67B8 /* backends.h in Headers */, + 61DB180D148BA9A9004A67B8 /* block.h in Headers */, 61DB180F148BA9A9004A67B8 /* codebook.h in Headers */, 61DB1810148BA9A9004A67B8 /* codec_internal.h in Headers */, 61DB1811148BA9A9004A67B8 /* config_types.h in Headers */, @@ -173,7 +193,9 @@ 61DB181F148BA9A9004A67B8 /* ogg.h in Headers */, 61DB1820148BA9A9004A67B8 /* os_types.h in Headers */, 61DB1821148BA9A9004A67B8 /* os.h in Headers */, + 61DB1823148BA9A9004A67B8 /* registry.h in Headers */, 61DB1828148BA9A9004A67B8 /* window_lookup.h in Headers */, + 61DB182A148BA9A9004A67B8 /* window.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -228,6 +250,7 @@ buildActionMask = 2147483647; files = ( 61DB180B148BA9A9004A67B8 /* bitwise.c in Sources */, + 61DB180C148BA9A9004A67B8 /* block.c in Sources */, 61DB180E148BA9A9004A67B8 /* codebook.c in Sources */, 61DB1812148BA9A9004A67B8 /* floor0.c in Sources */, 61DB1813148BA9A9004A67B8 /* floor1.c in Sources */, @@ -235,11 +258,12 @@ 61DB1815148BA9A9004A67B8 /* info.c in Sources */, 61DB181A148BA9A9004A67B8 /* mapping0.c in Sources */, 61DB181C148BA9A9004A67B8 /* mdct.c in Sources */, + 61DB1822148BA9A9004A67B8 /* registry.c in Sources */, 61DB1824148BA9A9004A67B8 /* res012.c in Sources */, + 61DB1825148BA9A9004A67B8 /* sharedbook.c in Sources */, + 61DB1826148BA9A9004A67B8 /* synthesis.c in Sources */, 61DB1827148BA9A9004A67B8 /* vorbisfile.c in Sources */, - 61E1A173160BCA4F002370D0 /* dsp.c in Sources */, - 61E1A174160BCA4F002370D0 /* floor_lookup.c in Sources */, - 61E1A175160BCA4F002370D0 /* misc.c in Sources */, + 61DB1829148BA9A9004A67B8 /* window.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/Makefile.am --- a/misc/libtremor/tremor/Makefile.am Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/Makefile.am Sun Oct 28 04:00:07 2012 +0100 @@ -2,19 +2,17 @@ INCLUDES = -I./ -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = vorbisidec.pc - lib_LTLIBRARIES = libvorbisidec.la -libvorbisidec_la_SOURCES = mdct.c dsp.c info.c misc.c \ +libvorbisidec_la_SOURCES = mdct.c block.c window.c \ + synthesis.c info.c \ floor1.c floor0.c vorbisfile.c \ - res012.c mapping0.c codebook.c \ - framing.c bitwise.c \ + res012.c mapping0.c registry.c codebook.c \ + sharedbook.c framing.c bitwise.c \ codebook.h misc.h mdct_lookup.h\ - os.h mdct.h ivorbisfile.h lsp_lookup.h\ - window_lookup.h floor_lookup.c \ - codec_internal.h ogg.h \ + os.h mdct.h block.h ivorbisfile.h lsp_lookup.h\ + registry.h window.h window_lookup.h\ + codec_internal.h backends.h ogg.h \ asm_arm.h ivorbiscodec.h libvorbisidec_la_LDFLAGS = -version-info @V_LIB_CURRENT@:@V_LIB_REVISION@:@V_LIB_AGE@ @@ -29,8 +27,6 @@ include_HEADERS = ivorbiscodec.h ivorbisfile.h ogg.h os_types.h config_types.h -EXTRA_DIST = vorbisidec.pc.in - example: -ln -fs . vorbis $(MAKE) ivorbisfile_example diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/autogen.sh --- a/misc/libtremor/tremor/autogen.sh Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/autogen.sh Sun Oct 28 04:00:07 2012 +0100 @@ -2,14 +2,16 @@ # Run this to set up the build system: configure, makefiles, etc. # (based on the version in enlightenment's cvs) -package="vorbisidec" +package="vorbisdec" +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." @@ -18,16 +20,72 @@ DIE=1 } -(automake --version) < /dev/null > /dev/null 2>&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 && { echo echo "You must have automake installed to compile $package." - 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 "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + exit 1 + } +fi -(libtool --version) < /dev/null > /dev/null 2>&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 || { echo echo "You must have libtool installed to compile $package." echo "Download the appropriate package for your system," @@ -47,15 +105,16 @@ echo "Generating configuration files for $package, please wait...." -echo " aclocal $ACLOCAL_FLAGS" -aclocal $ACLOCAL_FLAGS || exit 1 +echo " $ACLOCAL $ACLOCAL_FLAGS" +$ACLOCAL $ACLOCAL_FLAGS || exit 1 +echo " $LIBTOOLIZE --automake" +$LIBTOOLIZE --automake || exit 1 echo " autoheader" autoheader || exit 1 -echo " libtoolize --automake" -libtoolize --automake || exit 1 -echo " automake --add-missing $AUTOMAKE_FLAGS" -automake --add-missing $AUTOMAKE_FLAGS || exit 1 +echo " $AUTOMAKE --add-missing $AUTOMAKE_FLAGS" +$AUTOMAKE --add-missing $AUTOMAKE_FLAGS || exit 1 echo " autoconf" autoconf || exit 1 -$srcdir/configure "$@" && echo +cd $olddir +$srcdir/configure --enable-maintainer-mode "$@" && echo diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/bitwise.c --- a/misc/libtremor/tremor/bitwise.c Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/bitwise.c Sun Oct 28 04:00:07 2012 +0100 @@ -20,7 +20,6 @@ #include #include -#include "misc.h" #include "ogg.h" static unsigned long mask[]= @@ -48,8 +47,8 @@ if(b->head->next){ b->count+=b->head->length; b->head=b->head->next; - b->headptr=b->head->buffer->data+b->head->begin-b->headend; - b->headend+=b->head->length; + 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 */ @@ -82,7 +81,7 @@ /* Read in bits without advancing the bitptr; bits <= 32 */ long oggpack_look(oggpack_buffer *b,int bits){ unsigned long m=mask[bits]; - unsigned long ret; + unsigned long ret=-1; bits+=b->headbit; @@ -92,22 +91,22 @@ 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); + ret|=*ptr++<<(8-b->headbit); if(bits>16){ --end; _lookspan(); - ret|=*ptr++<<(16-b->headbit); + ret|=*ptr++<<(16-b->headbit); if(bits>24){ --end; _lookspan(); - ret|=*ptr++<<(24-b->headbit); + ret|=*ptr++<<(24-b->headbit); if(bits>32 && b->headbit){ --end; _lookspan(); @@ -147,6 +146,27 @@ if((b->headend-=bits/8)<1)_span(b); } +/* spans forward and finds next byte. Never halts */ +static void _span_one(oggpack_buffer *b){ + while(b->headend<1){ + if(b->head->next){ + b->count+=b->head->length; + b->head=b->head->next; + b->headptr=b->head->buffer->data+b->head->begin; + b->headend=b->head->length; + }else + break; + } +} + +static int _halt_one(oggpack_buffer *b){ + if(b->headend<1){ + _adv_halt(b); + return -1; + } + return 0; +} + int oggpack_eop(oggpack_buffer *b){ if(b->headend<0)return -1; return 0; @@ -154,9 +174,83 @@ /* bits <= 32 */ long oggpack_read(oggpack_buffer *b,int bits){ - long ret=oggpack_look(b,bits); - oggpack_adv(b,bits); - return(ret); + unsigned long m=mask[bits]; + ogg_uint32_t ret=-1; + + bits+=b->headbit; + + if(bits >= b->headend<<3){ + + if(b->headend<0)return -1; + + if(bits){ + if (_halt_one(b)) return -1; + ret=*b->headptr>>b->headbit; + + if(bits>=8){ + ++b->headptr; + --b->headend; + _span_one(b); + if(bits>8){ + if (_halt_one(b)) return -1; + ret|=*b->headptr<<(8-b->headbit); + + if(bits>=16){ + ++b->headptr; + --b->headend; + _span_one(b); + if(bits>16){ + if (_halt_one(b)) return -1; + ret|=*b->headptr<<(16-b->headbit); + + if(bits>=24){ + ++b->headptr; + --b->headend; + _span_one(b); + if(bits>24){ + if (_halt_one(b)) return -1; + ret|=*b->headptr<<(24-b->headbit); + + if(bits>=32){ + ++b->headptr; + --b->headend; + _span_one(b); + if(bits>32){ + if (_halt_one(b)) return -1; + if(b->headbit)ret|=*b->headptr<<(32-b->headbit); + + } + } + } + } + } + } + } + } + } + }else{ + + 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); + } + } + } + } + + b->headptr+=bits/8; + b->headend-=bits/8; + } + + ret&=m; + b->headbit=bits&7; + return ret; } long oggpack_bytes(oggpack_buffer *b){ diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/codebook.c --- a/misc/libtremor/tremor/codebook.c Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/codebook.c Sun Oct 28 04:00:07 2012 +0100 @@ -22,324 +22,11 @@ #include "ivorbiscodec.h" #include "codebook.h" #include "misc.h" -#include "os.h" - -/**** pack/unpack helpers ******************************************/ -int _ilog(unsigned int v){ - int ret=0; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -static ogg_uint32_t decpack(long entry,long used_entry,long quantvals, - codebook *b,oggpack_buffer *opb,int maptype){ - ogg_uint32_t ret=0; - int j; - - switch(b->dec_type){ - - case 0: - return (ogg_uint32_t)entry; - - case 1: - if(maptype==1){ - /* vals are already read into temporary colum vector here */ - for(j=0;jdim;j++){ - ogg_uint32_t off=entry%quantvals; - entry/=quantvals; - ret|=((ogg_uint16_t *)(b->q_val))[off]<<(b->q_bits*j); - } - }else{ - for(j=0;jdim;j++) - ret|=oggpack_read(opb,b->q_bits)<<(b->q_bits*j); - } - return ret; - - case 2: - for(j=0;jdim;j++){ - ogg_uint32_t off=entry%quantvals; - entry/=quantvals; - ret|=off<<(b->q_pack*j); - } - return ret; - - case 3: - return (ogg_uint32_t)used_entry; - - } -} - -/* 32 bit float (not IEEE; nonnormalized mantissa + - biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm - Why not IEEE? It's just not that important here. */ - -static 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,ogg_uint32_t *r,long quantvals, - codebook *b, oggpack_buffer *opb,int maptype){ - long i,j,count=0; - long top=0; - ogg_uint32_t marker[33]; - - if(n<2){ - r[0]=0x80000000; - }else{ - memset(marker,0,sizeof(marker)); - - for(i=0;i>(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, - oggpack_buffer *opb,int maptype){ - int i; - ogg_uint32_t *work; - - if(s->dec_nodeb==4){ - s->dec_table=_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=_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;iused_entries*2-2;i++) - ((unsigned char *)s->dec_table)[i]= - ((work[i] & 0x80000000UL) >> 24) | work[i]; - break; - case 2: - for(i=0;iused_entries*2-2;i++) - ((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{ - ogg_uint16_t *out=(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*dimentries); - int vals=b->entries>>((bits-1)*(b->dim-1)/b->dim); - - while(1){ - long acc=1; - long acc1=1; - int i; - for(i=0;idim;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)_ogg_free(b->q_val); - if(b->dec_table)_ogg_free(b->dec_table); - - memset(b,0,sizeof(*b)); -} - -int vorbis_book_unpack(oggpack_buffer *opb,codebook *s){ - char *lengthlist=NULL; - int quantvals=0; - long i,j,k; - int maptype; - +/* unpacks a codebook from the packet buffer into the codebook struct, + readies the codebook auxiliary structures for decode *************/ +int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){ + long i,j; memset(s,0,sizeof(*s)); /* make sure alignment is correct */ @@ -354,7 +41,7 @@ switch((int)oggpack_read(opb,1)){ case 0: /* unordered */ - lengthlist=(char *)alloca(sizeof(*lengthlist)*s->entries); + s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); /* allocated but unused entries? */ if(oggpack_read(opb,1)){ @@ -364,20 +51,16 @@ if(oggpack_read(opb,1)){ long num=oggpack_read(opb,5); if(num==-1)goto _eofout; - lengthlist[i]=num+1; - s->used_entries++; - if(num+1>s->dec_maxlength)s->dec_maxlength=num+1; + s->lengthlist[i]=num+1; }else - lengthlist[i]=0; + s->lengthlist[i]=0; } }else{ /* all entries used; no tagging */ - s->used_entries=s->entries; for(i=0;ientries;i++){ long num=oggpack_read(opb,5); if(num==-1)goto _eofout; - lengthlist[i]=num+1; - if(num+1>s->dec_maxlength)s->dec_maxlength=num+1; + s->lengthlist[i]=num+1; } } @@ -386,16 +69,13 @@ /* ordered */ { long length=oggpack_read(opb,5)+1; + s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); - s->used_entries=s->entries; - lengthlist=(char *)alloca(sizeof(*lengthlist)*s->entries); - for(i=0;ientries;){ long num=oggpack_read(opb,_ilog(s->entries-i)); if(num==-1)goto _eofout; for(j=0;jentries;j++,i++) - lengthlist[i]=length; - s->dec_maxlength=length; + s->lengthlist[i]=length; length++; } } @@ -404,155 +84,91 @@ /* EOF */ return(-1); } - - + /* Do we have a mapping to unpack? */ - - if((maptype=oggpack_read(opb,4))>0){ - s->q_min=_float32_unpack(oggpack_read(opb,32),&s->q_minp); - s->q_del=_float32_unpack(oggpack_read(opb,32),&s->q_delp); - s->q_bits=oggpack_read(opb,4)+1; - s->q_seq=oggpack_read(opb,1); - - s->q_del>>=s->q_bits; - s->q_delp+=s->q_bits; - } - - switch(maptype){ + switch((s->maptype=oggpack_read(opb,4))){ case 0: - - /* 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; + /* no mapping */ + break; + case 1: case 2: + /* implicitly populated value mapping */ + /* explicitly populated value mapping */ - if(_make_decode_table(s,lengthlist,quantvals,opb,maptype)) goto _errout; - break; - - 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 */ - { - /* 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; - - - if(total1<=4 && total1<=total2){ - /* use dec_type 1: vector of packed values */ - - /* need quantized values before */ - s->q_val=alloca(sizeof(ogg_uint16_t)*quantvals); - for(i=0;iq_val)[i]=oggpack_read(opb,s->q_bits); - - if(oggpack_eop(opb)){ - s->q_val=0; /* cleanup must not free alloca memory */ - goto _eofout; - } + s->q_min=oggpack_read(opb,32); + s->q_delta=oggpack_read(opb,32); + s->q_quant=oggpack_read(opb,4)+1; + s->q_sequencep=oggpack_read(opb,1); - s->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=_ogg_malloc(quantvals); - for(i=0;iq_val)[i]=oggpack_read(opb,s->q_bits); - }else{ - s->q_val=_ogg_malloc(quantvals*2); - for(i=0;iq_val)[i]=oggpack_read(opb,s->q_bits); - } - - if(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; - + { + int quantvals=0; + switch(s->maptype){ + case 1: + quantvals=_book_maptype1_quantvals(s); + break; + case 2: + quantvals=s->entries*s->dim; + break; } - } - 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; - }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=_ogg_malloc(s->q_pack*s->used_entries); - - if(s->q_bits<=8){ - for(i=0;iused_entries*s->dim;i++) - ((unsigned char *)(s->q_val))[i]=oggpack_read(opb,s->q_bits); - }else{ - for(i=0;iused_entries*s->dim;i++) - ((ogg_uint16_t *)(s->q_val))[i]=oggpack_read(opb,s->q_bits); - } + /* quantized values */ + s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals); + for(i=0;iquantlist[i]=oggpack_read(opb,s->q_quant); + + if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout; } break; default: goto _errout; } - if(oggpack_eop(opb))goto _eofout; - - return 0; + /* all set */ + return(0); + _errout: _eofout: - vorbis_book_clear(s); - return -1; + vorbis_staticbook_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); } -static inline ogg_uint32_t decode_packed_entry_number(codebook *book, - oggpack_buffer *b){ - ogg_uint32_t chase=0; +STIN long decode_packed_entry_number(codebook *book, + oggpack_buffer *b){ int read=book->dec_maxlength; - long lok = oggpack_look(b,read),i; - + 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); + while(lok<0 && read>1) lok = oggpack_look(b, --read); @@ -561,229 +177,195 @@ return -1; } - /* 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>i)&1)]; - if(chase&0x80UL)break; - } - chase&=0x7fUL; + /* bisect search for the codeword in the ordered list */ + { + ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok); - }else{ - - /* 8/16 */ - unsigned char *t=(unsigned char *)book->dec_table; - for(i=0;i>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; + while(hi-lo>1){ + long p=(hi-lo)>>1; + long test=book->codelist[lo+p]>testword; + lo+=p&(test-1); + hi-=p&(-test); } - }else{ - if(book->dec_nodeb==2){ - if(book->dec_leafw==1){ - - /* 16/16 */ - for(i=0;idec_table))[chase*2+((lok>>i)&1)]; - if(chase&0x8000UL)break; - } - chase&=0x7fffUL; - - }else{ - - /* 16/32 */ - ogg_uint16_t *t=(ogg_uint16_t *)book->dec_table; - for(i=0;i>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;idec_table))[chase*2+((lok>>i)&1)]; - if(chase&0x80000000UL)break; - } - chase&=0x7fffffffUL; - + if(book->dec_codelengths[lo]<=read){ + oggpack_adv(b, book->dec_codelengths[lo]); + return(lo); } } - if(i declarative (set the value) + addmul==1 -> additive + addmul==2 -> multiplicitive */ + /* returns the [original, not compacted] entry number or -1 on eof *********/ long vorbis_book_decode(codebook *book, oggpack_buffer *b){ - if(book->dec_type)return -1; - return decode_packed_entry_number(book,b); -} - -int decode_map(codebook *s, oggpack_buffer *b, ogg_int32_t *v, int point){ - ogg_uint32_t entry = decode_packed_entry_number(s,b); - int i; - if(oggpack_eop(b))return(-1); - - /* according to decode type */ - switch(s->dec_type){ - case 1:{ - /* packed vector of values */ - int mask=(1<q_bits)-1; - for(i=0;idim;i++){ - v[i]=entry&mask; - entry>>=s->q_bits; - } - break; - } - case 2:{ - /* packed vector of column offsets */ - int mask=(1<q_pack)-1; - for(i=0;idim;i++){ - if(s->q_bits<=8) - v[i]=((unsigned char *)(s->q_val))[entry&mask]; - else - v[i]=((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; - - if(s->q_bits<=8){ - for(i=0;idim;i++) - v[i]=((unsigned char *)ptr)[i]; - }else{ - for(i=0;idim;i++) - v[i]=((ogg_uint16_t *)ptr)[i]; - } - break; - } - default: - return -1; + 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; - 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;idim;i++) - v[i]= add + ((v[i] * s->q_del) >> shiftM); - else - for(i=0;idim;i++) - v[i]= add + ((v[i] * s->q_del) << -shiftM); - - if(s->q_seq) - for(i=1;idim;i++) - v[i]+=v[i-1]; - } - - return 0; + /* if there's no dec_index, the codebook unpacking isn't collapsed */ + return(-1); } /* returns 0 on OK or -1 on eof *************************************/ long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, oggpack_buffer *b,int n,int point){ - if(book->used_entries>0){ + if(book->used_entries>0){ int step=n/book->dim; - ogg_int32_t *v = (ogg_int32_t *)alloca(sizeof(*v)*book->dim); + long *entry = (long *)alloca(sizeof(*entry)*step); + ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step); int i,j,o; + int shift=point-book->binarypoint; - for (j=0;jdim;i++,o+=step) - a[o]+=v[i]; + 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;idim;i++,o+=step) + for (j=0;j>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;idim;i++,o+=step) + for (j=0;jused_entries>0){ - ogg_int32_t *v = (ogg_int32_t *)alloca(sizeof(*v)*book->dim); - int i,j; + int i,j,entry; + ogg_int32_t *t; + int shift=point-book->binarypoint; - for(i=0;idim;j++) - a[i++]+=v[j]; + if(shift>=0){ + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;) + a[i++]+=t[j++]>>shift; + } + }else{ + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;) + a[i++]+=t[j++]<<-shift; + } } } - return 0; + return(0); } long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a, oggpack_buffer *b,int n,int point){ if(book->used_entries>0){ - ogg_int32_t *v = (ogg_int32_t *)alloca(sizeof(*v)*book->dim); - int i,j; + int i,j,entry; + ogg_int32_t *t; + int shift=point-book->binarypoint; - for(i=0;idim;j++) - a[i++]=v[j]; + if(shift>=0){ + + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;){ + a[i++]=t[j++]>>shift; + } + } + }else{ + + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;){ + a[i++]=t[j++]<<-shift; + } + } } }else{ + int i,j; - for(i=0;idim;j++) + for (j=0;jdim;){ a[i++]=0; + } } } - - return 0; + return(0); } -long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, +long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,\ long offset,int ch, oggpack_buffer *b,int n,int point){ - if(book->used_entries>0){ - ogg_int32_t *v = (ogg_int32_t *)alloca(sizeof(*v)*book->dim); - long i,j; + long i,j,entry; int chptr=0; + int shift=point-book->binarypoint; - for(i=offset;idim;j++){ - a[chptr++][i]+=v[j]; - if(chptr==ch){ - chptr=0; - i++; + if(shift>=0){ + + for(i=offset;ivaluelist+entry*book->dim; + for (j=0;jdim;j++){ + a[chptr++][i]+=t[j]>>shift; + if(chptr==ch){ + chptr=0; + i++; + } + } + } + } + }else{ + + for(i=offset;ivaluelist+entry*book->dim; + for (j=0;jdim;j++){ + a[chptr++][i]+=t[j]<<-shift; + if(chptr==ch){ + chptr=0; + i++; + } + } } } } } - return 0; + return(0); } diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/codebook.h --- a/misc/libtremor/tremor/codebook.h Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/codebook.h Sun Oct 28 04:00:07 2012 +0100 @@ -20,33 +20,70 @@ #include "ogg.h" -typedef struct codebook{ - long dim; /* codebook dimensions (elements per vector) */ - long entries; /* codebook entries */ - long used_entries; /* populated codebook entries */ +/* 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 */ - 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 */ + /* 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; - ogg_int32_t q_min; - int q_minp; - ogg_int32_t q_del; - int q_delp; - int q_seq; - int q_bits; - int q_pack; - void *q_val; +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 */ } codebook; +extern void vorbis_staticbook_clear(static_codebook *b); +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 int vorbis_book_unpack(oggpack_buffer *b,codebook *c); +extern long _book_maptype1_quantvals(const static_codebook *b); + +extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c); extern long vorbis_book_decode(codebook *book, oggpack_buffer *b); extern long vorbis_book_decodevs_add(codebook *book, ogg_int32_t *a, diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/codec_internal.h --- a/misc/libtremor/tremor/codec_internal.h Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/codec_internal.h Sun Oct 28 04:00:07 2012 +0100 @@ -6,7 +6,7 @@ * 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 OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * * * ******************************************************************** @@ -18,149 +18,36 @@ #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_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; - oggpack_buffer opb; - - ogg_int32_t **work; - ogg_int32_t **mdctright; - int out_begin; - int out_end; - - long lW; - long W; - - ogg_int64_t granulepos; - ogg_int64_t sequence; - ogg_int64_t sample_count; - -}; - - -/* Floor backend generic *****************************************/ - -extern vorbis_info_floor *floor0_info_unpack(vorbis_info *,oggpack_buffer *); -extern void floor0_free_info(vorbis_info_floor *); -extern int floor0_memosize(vorbis_info_floor *); -extern ogg_int32_t *floor0_inverse1(struct vorbis_dsp_state *, - vorbis_info_floor *,ogg_int32_t *); -extern int floor0_inverse2 (struct vorbis_dsp_state *,vorbis_info_floor *, - ogg_int32_t *buffer,ogg_int32_t *); - -extern vorbis_info_floor *floor1_info_unpack(vorbis_info *,oggpack_buffer *); -extern void floor1_free_info(vorbis_info_floor *); -extern int floor1_memosize(vorbis_info_floor *); -extern ogg_int32_t *floor1_inverse1(struct vorbis_dsp_state *, - vorbis_info_floor *,ogg_int32_t *); -extern int floor1_inverse2 (struct vorbis_dsp_state *,vorbis_info_floor *, - ogg_int32_t *buffer,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<>(INVSQ_LOOKUP_I_SHIFT-1); long d=a&INVSQ_LOOKUP_I_MASK; /* 0.10 */ long val=INVSQ_LOOKUP_I[i]- /* 1.16 */ @@ -49,60 +60,60 @@ /* interpolated lookup based fromdB function, domain -140dB to 0dB only */ /* a is in n.12 format */ -#ifdef _LOW_ACCURACY_ -static inline 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; +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] * FROMdB2_LOOKUP[i&FROMdB2_MASK]; } -#else -static inline 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 */ -static inline ogg_int32_t vorbis_coslook_i(long a){ +STIN 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 half-wave lookup based cos function */ +/* interpolated lookup based cos function */ /* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */ -static inline 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-LSP_FRACBITS+14); +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-LSP_FRACBITS+14); + } + + return(a); } -static const 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 +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 }; /* used in init only; interpolate the long way */ -static inline ogg_int32_t toBARK(int n){ +STIN ogg_int32_t toBARK(int n){ int i; - for(i=0;i<54;i++) + for(i=0;i<27;i++) if(n>=barklook[i] && n>17); + int gap=barklook[i+1]-barklook[i]; + int del=n-barklook[i]; + + return((i<<15)+((del<<15)/gap)); } } @@ -122,11 +133,11 @@ 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 n,int ln, +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 nyq){ + ogg_int32_t *icos){ /* 0 <= m < 256 */ @@ -135,27 +146,6 @@ int ampoffseti=ampoffset*4096; int ampi=amp; ogg_int32_t *ilsp=(ogg_int32_t *)alloca(m*sizeof(*ilsp)); - - ogg_uint32_t inyq= (1UL<<31) / toBARK(nyq); - ogg_uint32_t imap= (1UL<<31) / ln; - 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_ - ogg_uint32_t nextbark=((tBnyq1<<11)/ln)>>12; -#else - 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>15); - + ogg_int32_t wi=icos[k]; #ifdef _V_LSP_MATH_ASM lsp_loop_asm(&qi,&pi,&qexp,ilsp,wi,m); @@ -215,9 +202,8 @@ for(j=3;j>25])) - if(!(shift=MLOOP_2[(pi|qi)>>19])) - shift=MLOOP_3[(pi|qi)>>16]; - + 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; @@ -225,7 +211,7 @@ 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){ @@ -293,57 +279,32 @@ amp>>=9; #endif curve[i]= MULT31_SHIFT15(curve[i],amp); - - while(++i=fdx){ - ferr-=fdx; - f++; - } - f+=fbase; - - if(f>=nextf)break; - - curve[i]= MULT31_SHIFT15(curve[i],amp); - } - - while(1){ - map++; - - if(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; - } + while(map[++i]==k) curve[i]= MULT31_SHIFT15(curve[i],amp); } } /*************** vorbis decode glue ************/ -void floor0_free_info(vorbis_info_floor *i){ +static void floor0_free_info(vorbis_info_floor *i){ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; - if(info)_ogg_free(info); + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); + } } -vorbis_info_floor *floor0_info_unpack (vorbis_info *vi,oggpack_buffer *opb){ +static void floor0_free_look(vorbis_look_floor *i){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + if(look){ + + if(look->linearmap)_ogg_free(look->linearmap); + if(look->lsp_look)_ogg_free(look->lsp_look); + memset(look,0,sizeof(*look)); + _ogg_free(look); + } +} + +static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; int j; @@ -358,13 +319,12 @@ 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;jnumbooks;j++){ info->books[j]=oggpack_read(opb,8); - if(info->books[j]>=ci->books)goto err_out; + if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out; } - - if(oggpack_eop(opb))goto err_out; return(info); err_out: @@ -372,35 +332,75 @@ return(NULL); } -int floor0_memosize(vorbis_info_floor *i){ +/* 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; vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; - return info->order+1; + 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;jn;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;jln;j++) + look->lsp_look[j]=vorbis_coslook2_i(0x10000*j/look->ln); + + return look; } -ogg_int32_t *floor0_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *i, - ogg_int32_t *lsp){ - vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; +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; int j,k; - int ampraw=oggpack_read(&vd->opb,info->ampbits); + int ampraw=oggpack_read(&vb->opb,info->ampbits); if(ampraw>0){ /* also handles the -1 out of data case */ long maxval=(1<ampbits)-1; int amp=((ampraw*info->ampdB)<<4)/maxval; - int booknum=oggpack_read(&vd->opb,_ilog(info->numbooks)); + int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); if(booknum!=-1 && booknumnumbooks){ /* be paranoid */ - codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; - codebook *b=ci->book_param+info->books[booknum]; + 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)); - for(j=0;jorder;j+=b->dim) - if(vorbis_book_decodev_set(b,lsp+j,&vd->opb,b->dim,-24)==-1)goto eop; - for(j=0;jorder;){ + for(j=0;jm;j+=b->dim) + if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim,-24)==-1)goto eop; + for(j=0;jm;){ for(k=0;kdim;k++,j++)lsp[j]+=last; last=lsp[j-1]; } - lsp[info->order]=amp; + lsp[look->m]=amp; return(lsp); } } @@ -408,21 +408,28 @@ return(NULL); } -int floor0_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *i, - ogg_int32_t *lsp,ogg_int32_t *out){ - vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; - codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; +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; - if(lsp){ - ogg_int32_t amp=lsp[info->order]; + if(memo){ + ogg_int32_t *lsp=(ogg_int32_t *)memo; + ogg_int32_t amp=lsp[look->m]; /* take the coefficients back to a spectral envelope curve */ - vorbis_lsp_to_curve(out,ci->blocksizes[vd->W]/2,info->barkmap, - lsp,info->order,amp,info->ampdB, - info->rate>>1); + vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln, + lsp,look->m,amp,info->ampdB,look->lsp_look); return(1); } - memset(out,0,sizeof(*out)*ci->blocksizes[vd->W]/2); + memset(out,0,sizeof(*out)*look->n); return(0); } +/* export hooks */ +vorbis_func_floor floor0_exportbundle={ + &floor0_unpack,&floor0_look,&floor0_free_info, + &floor0_free_look,&floor0_inverse1,&floor0_inverse2 +}; + + diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/floor1.c --- a/misc/libtremor/tremor/floor1.c Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/floor1.c Sun Oct 28 04:00:07 2012 +0100 @@ -6,7 +6,7 @@ * 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 OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * * * ******************************************************************** @@ -21,29 +21,44 @@ #include "ogg.h" #include "ivorbiscodec.h" #include "codec_internal.h" +#include "registry.h" #include "codebook.h" #include "misc.h" +#include "block.h" -extern const ogg_int32_t FLOOR_fromdB_LOOKUP[]; #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */ -#define VIF_POSIT 63 + +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; /***********************************************/ -void floor1_free_info(vorbis_info_floor *i){ +static void floor1_free_info(vorbis_info_floor *i){ vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; if(info){ - if(info->class)_ogg_free(info->class); - if(info->partitionclass)_ogg_free(info->partitionclass); - if(info->postlist)_ogg_free(info->postlist); - if(info->forward_index)_ogg_free(info->forward_index); - if(info->hineighbor)_ogg_free(info->hineighbor); - if(info->loneighbor)_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); + } +} + static int ilog(unsigned int v){ int ret=0; while(v){ @@ -53,41 +68,31 @@ return(ret); } -static int icomp(const void *a,const void *b){ - return(**(ogg_uint16_t **)a-**(ogg_uint16_t **)b); -} - -vorbis_info_floor *floor1_info_unpack (vorbis_info *vi,oggpack_buffer *opb){ +static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; int j,k,count=0,maxclass=-1,rangebits; - ogg_uint16_t *sortpointer[VIF_POSIT+2]; - + vorbis_info_floor1 *info=(vorbis_info_floor1 *)_ogg_calloc(1,sizeof(*info)); /* read partitions */ info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */ - info->partitionclass= - (char *)_ogg_malloc(info->partitions*sizeof(*info->partitionclass)); for(j=0;jpartitions;j++){ info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */ if(maxclasspartitionclass[j])maxclass=info->partitionclass[j]; } /* read partition classes */ - info->class= - (floor1class *)_ogg_malloc((maxclass+1)*sizeof(*info->class)); for(j=0;jclass[j].class_dim=oggpack_read(opb,3)+1; /* 1 to 8 */ - info->class[j].class_subs=oggpack_read(opb,2); /* 0,1,2,3 bits */ - if(oggpack_eop(opb)<0) goto err_out; - if(info->class[j].class_subs) - info->class[j].class_book=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<class[j].class_subs);k++){ - info->class[j].class_subbook[k]=oggpack_read(opb,8)-1; - if(info->class[j].class_subbook[k]>=ci->books && - info->class[j].class_subbook[k]!=0xff)goto err_out; + 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<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; } } @@ -95,61 +100,16 @@ info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */ rangebits=oggpack_read(opb,4); - for(j=0,k=0;jpartitions;j++) - count+=info->class[info->partitionclass[j]].class_dim; - info->postlist= - (ogg_uint16_t *)_ogg_malloc((count+2)*sizeof(*info->postlist)); - info->forward_index= - (char *)_ogg_malloc((count+2)*sizeof(*info->forward_index)); - info->loneighbor= - (char *)_ogg_malloc(count*sizeof(*info->loneighbor)); - info->hineighbor= - (char *)_ogg_malloc(count*sizeof(*info->hineighbor)); - - count=0; for(j=0,k=0;jpartitions;j++){ - count+=info->class[info->partitionclass[j]].class_dim; - if(count>VIF_POSIT)goto err_out; + count+=info->class_dim[info->partitionclass[j]]; for(;kpostlist[k+2]=oggpack_read(opb,rangebits); - if(t>=(1<=(1<postlist[0]=0; info->postlist[1]=1<posts=count+2; - - /* also store a sorted position index */ - for(j=0;jposts;j++)sortpointer[j]=info->postlist+j; - qsort(sortpointer,info->posts,sizeof(*sortpointer),icomp); - - /* points from sort order back to range number */ - for(j=0;jposts;j++) - info->forward_index[j]=sortpointer[j]-info->postlist; - - /* discover our neighbors for decode where we don't use fit flags - (that would push the neighbors outward) */ - for(j=0;jposts-2;j++){ - int lo=0; - int hi=1; - int lx=0; - int hx=info->postlist[1]; - int currentx=info->postlist[j+2]; - for(k=0;kpostlist[k]; - if(x>lx && xcurrentx){ - hi=k; - hx=x; - } - } - info->loneighbor[j]=lo; - info->hineighbor[j]=hi; - } return(info); @@ -158,6 +118,81 @@ return(NULL); } +static int icomp(const void *a,const void *b){ + return(**(int **)a-**(int **)b); +} + +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;ipartitions;i++)n+=info->class_dim[info->partitionclass[i]]; + n+=2; + look->posts=n; + + /* also store a sorted position index */ + for(i=0;ipostlist+i; + qsort(sortpointer,n,sizeof(*sortpointer),icomp); + + /* points from sort order back to range number */ + for(i=0;iforward_index[i]=sortpointer[i]-info->postlist; + + /* 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;in; + int currentx=info->postlist[i+2]; + for(j=0;jpostlist[j]; + if(x>lx && xcurrentx){ + hi=j; + hx=x; + } + } + look->loneighbor[i]=lo; + look->hineighbor[i]=hi; + } + + return(look); +} + static int render_point(int x0,int x1,int y0,int y1,int x){ y0&=0x7fff; /* mask off flag */ y1&=0x7fff; @@ -174,6 +209,79 @@ } } +#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){ int dy=y1-y0; int adx=x1-x0; @@ -202,48 +310,42 @@ } } -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}; - -ogg_int32_t *floor1_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *in, - ogg_int32_t *fit_value){ - vorbis_info_floor1 *info=(vorbis_info_floor1 *)in; - codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; +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 i,j,k; - codebook *books=ci->book_param; - int quant_q=quant_look[info->mult-1]; - + codebook *books=ci->fullbooks; + /* unpack wrapped/predicted values from stream */ - if(oggpack_read(&vd->opb,1)==1){ - fit_value[0]=oggpack_read(&vd->opb,ilog(quant_q-1)); - fit_value[1]=oggpack_read(&vd->opb,ilog(quant_q-1)); + 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)); /* partition by partition */ /* partition by partition */ for(i=0,j=2;ipartitions;i++){ int classv=info->partitionclass[i]; - int cdim=info->class[classv].class_dim; - int csubbits=info->class[classv].class_subs; + int cdim=info->class_dim[classv]; + int csubbits=info->class_subs[classv]; int csub=1<class[classv].class_book,&vd->opb); + cval=vorbis_book_decode(books+info->class_book[classv],&vb->opb); if(cval==-1)goto eop; } for(k=0;kclass[classv].class_subbook[cval&(csub-1)]; + int book=info->class_subbook[classv][cval&(csub-1)]; cval>>=csubbits; - if(book!=0xff){ - if((fit_value[j+k]=vorbis_book_decode(books+book,&vd->opb))==-1) + if(book>=0){ + if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1) goto eop; }else{ fit_value[j+k]=0; @@ -253,13 +355,13 @@ } /* unwrap positive values and reconsitute via linear interpolation */ - for(i=2;iposts;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]], + for(i=2;iposts;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]], info->postlist[i]); - int hiroom=quant_q-predicted; + int hiroom=look->quant_q-predicted; int loroom=predicted; int room=(hiroomloneighbor[i-2]]&=0x7fff; - fit_value[info->hineighbor[i-2]]&=0x7fff; + fit_value[look->loneighbor[i-2]]&=0x7fff; + fit_value[look->hineighbor[i-2]]&=0x7fff; }else{ fit_value[i]=predicted|0x8000; @@ -295,21 +397,23 @@ return(NULL); } -int floor1_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *in, - ogg_int32_t *fit_value,ogg_int32_t *out){ - vorbis_info_floor1 *info=(vorbis_info_floor1 *)in; +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; - codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; - int n=ci->blocksizes[vd->W]/2; + codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup; + int n=ci->blocksizes[vb->W]/2; int j; - if(fit_value){ + if(memo){ /* render the lines */ + int *fit_value=(int *)memo; int hx=0; int lx=0; int ly=fit_value[0]*info->mult; - for(j=1;jposts;j++){ - int current=info->forward_index[j]; + for(j=1;jposts;j++){ + int current=look->forward_index[j]; int hy=fit_value[current]&0x7fff; if(hy==fit_value[current]){ @@ -328,3 +432,10 @@ 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 -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/framing.c --- a/misc/libtremor/tremor/framing.c Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/framing.c Sun Oct 28 04:00:07 2012 +0100 @@ -156,11 +156,19 @@ } /* 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 ogg_reference *ogg_buffer_sub(ogg_reference *or,long length){ + and increment buffer refcount. If the desired segment begins out + of range, NULL is returned; if the desired segment is simply zero + length, a zero length ref is returned. Partial range overlap + returns the overlap of the ranges */ +static ogg_reference *ogg_buffer_sub(ogg_reference *or,long begin,long length){ ogg_reference *ret=0,*head=0; - + + /* walk past any preceeding fragments we don't want */ + while(or && begin>=or->length){ + begin-=or->length; + or=or->next; + } + /* duplicate the reference chain; increment refcounts */ while(or && length){ ogg_reference *temp=_fetch_ref(or->buffer->ptr.owner); @@ -170,11 +178,12 @@ ret=temp; head=temp; head->buffer=or->buffer; - head->begin=or->begin; + head->begin=or->begin+begin; head->length=length; - if(head->length>or->length) - head->length=or->length; + if(head->length>or->length-begin) + head->length=or->length-begin; + begin=0; length-=head->length; or=or->next; } @@ -418,43 +427,43 @@ int ogg_page_version(ogg_page *og){ oggbyte_buffer ob; - if(oggbyte_init(&ob,og->header))return -1; + oggbyte_init(&ob,og->header); return oggbyte_read1(&ob,4); } int ogg_page_continued(ogg_page *og){ oggbyte_buffer ob; - if(oggbyte_init(&ob,og->header))return -1; + oggbyte_init(&ob,og->header); return oggbyte_read1(&ob,5)&0x01; } int ogg_page_bos(ogg_page *og){ oggbyte_buffer ob; - if(oggbyte_init(&ob,og->header))return -1; + oggbyte_init(&ob,og->header); return oggbyte_read1(&ob,5)&0x02; } int ogg_page_eos(ogg_page *og){ oggbyte_buffer ob; - if(oggbyte_init(&ob,og->header))return -1; + oggbyte_init(&ob,og->header); return oggbyte_read1(&ob,5)&0x04; } ogg_int64_t ogg_page_granulepos(ogg_page *og){ oggbyte_buffer ob; - if(oggbyte_init(&ob,og->header))return -1; + oggbyte_init(&ob,og->header); return oggbyte_read8(&ob,6); } ogg_uint32_t ogg_page_serialno(ogg_page *og){ oggbyte_buffer ob; - if(oggbyte_init(&ob,og->header)) return 0xffffffffUL; + oggbyte_init(&ob,og->header); return oggbyte_read4(&ob,14); } ogg_uint32_t ogg_page_pageno(ogg_page *og){ oggbyte_buffer ob; - if(oggbyte_init(&ob,og->header))return 0xffffffffUL; + oggbyte_init(&ob,og->header); return oggbyte_read4(&ob,18); } @@ -1070,7 +1079,7 @@ _next_lace(&ob,os); }else{ if(op){ - op->packet=ogg_buffer_sub(os->body_tail,os->body_fill&FINMASK); + op->packet=ogg_buffer_sub(os->body_tail,0,os->body_fill&FINMASK); op->bytes=os->body_fill&FINMASK; } } diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/info.c --- a/misc/libtremor/tremor/info.c Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/info.c Sun Oct 28 04:00:07 2012 +0100 @@ -25,8 +25,9 @@ #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){ @@ -95,8 +96,8 @@ if(vc->user_comments)_ogg_free(vc->user_comments); if(vc->comment_lengths)_ogg_free(vc->comment_lengths); if(vc->vendor)_ogg_free(vc->vendor); + memset(vc,0,sizeof(*vc)); } - memset(vc,0,sizeof(*vc)); } /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. @@ -118,35 +119,31 @@ if(ci){ - if(ci->mode_param)_ogg_free(ci->mode_param); + for(i=0;imodes;i++) + if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); - if(ci->map_param){ - for(i=0;imaps;i++) /* unpack does the range checking */ - mapping_clear_info(ci->map_param+i); - _ogg_free(ci->map_param); - } + for(i=0;imaps;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->floor_param){ - for(i=0;ifloors;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]); - _ogg_free(ci->floor_param); - _ogg_free(ci->floor_type); - } + for(i=0;ifloors;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;iresidues;i++) /* unpack does the range checking */ + if(ci->residue_param[i]) + _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); - if(ci->residue_param){ - for(i=0;iresidues;i++) /* unpack does the range checking */ - res_clear_info(ci->residue_param+i); - _ogg_free(ci->residue_param); + for(i=0;ibooks;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->book_param){ - for(i=0;ibooks;i++) - vorbis_book_clear(ci->book_param+i); - _ogg_free(ci->book_param); - } + if(ci->fullbooks) + _ogg_free(ci->fullbooks); _ogg_free(ci); } @@ -222,53 +219,70 @@ /* codebooks */ ci->books=oggpack_read(opb,8)+1; - ci->book_param=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->book_param)); - for(i=0;ibooks;i++) - if(vorbis_book_unpack(opb,ci->book_param+i))goto err_out; + /*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/ + for(i=0;ibooks;i++){ + ci->book_param[i]=(static_codebook *)_ogg_calloc(1,sizeof(*ci->book_param[i])); + if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out; + } - /* time backend settings, not actually used */ - i=oggpack_read(opb,6); - for(;i>=0;i--) - if(oggpack_read(opb,16)!=0)goto err_out; + /* time backend settings */ + ci->times=oggpack_read(opb,6)+1; + /*ci->time_type=_ogg_malloc(ci->times*sizeof(*ci->time_type));*/ + /*ci->time_param=_ogg_calloc(ci->times,sizeof(void *));*/ + for(i=0;itimes;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;*/ + } /* floor backend settings */ ci->floors=oggpack_read(opb,6)+1; - ci->floor_param=_ogg_malloc(sizeof(*ci->floor_param)*ci->floors); - ci->floor_type=_ogg_malloc(sizeof(*ci->floor_type)*ci->floors); + /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/ + /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/ for(i=0;ifloors;i++){ ci->floor_type[i]=oggpack_read(opb,16); if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out; - if(ci->floor_type[i]) - ci->floor_param[i]=floor1_info_unpack(vi,opb); - else - ci->floor_param[i]=floor0_info_unpack(vi,opb); + ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb); if(!ci->floor_param[i])goto err_out; } /* residue backend settings */ ci->residues=oggpack_read(opb,6)+1; - ci->residue_param=_ogg_malloc(sizeof(*ci->residue_param)*ci->residues); - for(i=0;iresidues;i++) - if(res_unpack(ci->residue_param+i,vi,opb))goto err_out; + /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/ + /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/ + for(i=0;iresidues;i++){ + ci->residue_type[i]=oggpack_read(opb,16); + if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out; + ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb); + if(!ci->residue_param[i])goto err_out; + } /* map backend settings */ ci->maps=oggpack_read(opb,6)+1; - ci->map_param=_ogg_malloc(sizeof(*ci->map_param)*ci->maps); + /*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/ + /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/ for(i=0;imaps;i++){ - if(oggpack_read(opb,16)!=0)goto err_out; - if(mapping_info_unpack(ci->map_param+i,vi,opb))goto err_out; + ci->map_type[i]=oggpack_read(opb,16); + if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out; + ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb); + if(!ci->map_param[i])goto err_out; } /* mode settings */ ci->modes=oggpack_read(opb,6)+1; - ci->mode_param= - (vorbis_info_mode *)_ogg_malloc(ci->modes*sizeof(*ci->mode_param)); + /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/ for(i=0;imodes;i++){ - ci->mode_param[i].blockflag=oggpack_read(opb,1); - if(oggpack_read(opb,16))goto err_out; - if(oggpack_read(opb,16))goto err_out; - ci->mode_param[i].mapping=oggpack_read(opb,8); - if(ci->mode_param[i].mapping>=ci->maps)goto err_out; + 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(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ @@ -284,7 +298,7 @@ with bitstream comments and a third packet that holds the codebook. */ -int vorbis_dsp_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ +int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ oggpack_buffer opb; if(op){ diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/ivorbiscodec.h --- a/misc/libtremor/tremor/ivorbiscodec.h Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/ivorbiscodec.h Sun Oct 28 04:00:07 2012 +0100 @@ -25,9 +25,6 @@ #include "ogg.h" -struct vorbis_dsp_state; -typedef struct vorbis_dsp_state vorbis_dsp_state; - typedef struct vorbis_info{ int version; int channels; @@ -56,7 +53,80 @@ 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; @@ -65,6 +135,18 @@ } 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); @@ -78,6 +160,22 @@ 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_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,int decodep); +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 -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/ivorbisfile.h --- a/misc/libtremor/tremor/ivorbisfile.h Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/ivorbisfile.h Sun Oct 28 04:00:07 2012 +0100 @@ -6,7 +6,7 @@ * 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 OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * * * ******************************************************************** @@ -26,6 +26,7 @@ #include #include "ivorbiscodec.h" +#define CHUNKSIZE 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 @@ -43,6 +44,12 @@ 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 { void *datasource; /* Pointer to a FILE *, etc. */ int seekable; @@ -57,8 +64,8 @@ ogg_int64_t *dataoffsets; ogg_uint32_t *serialnos; ogg_int64_t *pcmlengths; - vorbis_info vi; - vorbis_comment vc; + vorbis_info *vi; + vorbis_comment *vc; /* Decoding working state local storage */ ogg_int64_t pcm_offset; @@ -71,7 +78,8 @@ 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_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ ov_callbacks callbacks; @@ -110,7 +118,7 @@ extern vorbis_info *ov_info(OggVorbis_File *vf,int link); extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); -extern long ov_read(OggVorbis_File *vf,void *buffer,int length, +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, int *bitstream); #ifdef __cplusplus diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/lsp_lookup.h --- a/misc/libtremor/tremor/lsp_lookup.h Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/lsp_lookup.h Sun Oct 28 04:00:07 2012 +0100 @@ -20,6 +20,34 @@ #include "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, +}; + #define INVSQ_LOOKUP_I_SHIFT 10 #define INVSQ_LOOKUP_I_MASK 1023 static const long INVSQ_LOOKUP_I[64+1]={ diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/mapping0.c --- a/misc/libtremor/tremor/mapping0.c Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/mapping0.c Sun Oct 28 04:00:07 2012 +0100 @@ -6,7 +6,7 @@ * 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 OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * * * ******************************************************************** @@ -24,17 +24,96 @@ #include "mdct.h" #include "codec_internal.h" #include "codebook.h" +#include "window.h" +#include "registry.h" #include "misc.h" -void mapping_clear_info(vorbis_info_mapping *info){ +/* 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; if(info){ - if(info->chmuxlist)_ogg_free(info->chmuxlist); - if(info->submaplist)_ogg_free(info->submaplist); - if(info->coupling)_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;imap->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;isubmaps;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; @@ -46,9 +125,9 @@ } /* also responsible for range checking */ -int mapping_info_unpack(vorbis_info_mapping *info,vorbis_info *vi, - oggpack_buffer *opb){ +static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){ int i; + vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)_ogg_calloc(1,sizeof(*info)); codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; memset(info,0,sizeof(*info)); @@ -59,12 +138,10 @@ if(oggpack_read(opb,1)){ info->coupling_steps=oggpack_read(opb,8)+1; - info->coupling= - _ogg_malloc(info->coupling_steps*sizeof(*info->coupling)); - + for(i=0;icoupling_steps;i++){ - int testM=info->coupling[i].mag=oggpack_read(opb,ilog(vi->channels)); - int testA=info->coupling[i].ang=oggpack_read(opb,ilog(vi->channels)); + int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels)); + int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels)); if(testM<0 || testA<0 || @@ -78,79 +155,68 @@ if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */ if(info->submaps>1){ - info->chmuxlist=_ogg_malloc(sizeof(*info->chmuxlist)*vi->channels); for(i=0;ichannels;i++){ info->chmuxlist[i]=oggpack_read(opb,4); if(info->chmuxlist[i]>=info->submaps)goto err_out; } } - - info->submaplist=_ogg_malloc(sizeof(*info->submaplist)*info->submaps); for(i=0;isubmaps;i++){ int temp=oggpack_read(opb,8); - info->submaplist[i].floor=oggpack_read(opb,8); - if(info->submaplist[i].floor>=ci->floors)goto err_out; - info->submaplist[i].residue=oggpack_read(opb,8); - if(info->submaplist[i].residue>=ci->residues)goto err_out; + if(temp>=ci->times)goto err_out; + info->floorsubmap[i]=oggpack_read(opb,8); + if(info->floorsubmap[i]>=ci->floors)goto err_out; + info->residuesubmap[i]=oggpack_read(opb,8); + if(info->residuesubmap[i]>=ci->residues)goto err_out; } - return 0; + return info; err_out: - mapping_clear_info(info); - return -1; + mapping0_free_info(info); + return(NULL); } -int mapping_inverse(vorbis_dsp_state *vd,vorbis_info_mapping *info){ +static int seq=0; +static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){ + vorbis_dsp_state *vd=vb->vd; vorbis_info *vi=vd->vi; codec_setup_info *ci=(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=ci->blocksizes[vd->W]; + 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); - int *nonzero= - (int *)alloca(sizeof(*nonzero)*vi->channels); - ogg_int32_t **floormemo= - (void **)alloca(sizeof(*floormemo)*vi->channels); + ogg_int32_t **pcmbundle=(ogg_int32_t **)alloca(sizeof(*pcmbundle)*vi->channels); + int *zerobundle=(int *)alloca(sizeof(*zerobundle)*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;ichannels;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 */ - 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]); - } - + int submap=info->chmuxlist[i]; + floormemo[i]=look->floor_func[submap]-> + inverse1(vb,look->floor_look[submap]); if(floormemo[i]) nonzero[i]=1; else nonzero[i]=0; - memset(vd->work[i],0,sizeof(*vd->work[i])*n/2); + memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2); } /* channel coupling can 'dirty' the nonzero listing */ for(i=0;icoupling_steps;i++){ - if(nonzero[info->coupling[i].mag] || - nonzero[info->coupling[i].ang]){ - nonzero[info->coupling[i].mag]=1; - nonzero[info->coupling[i].ang]=1; + if(nonzero[info->coupling_mag[i]] || + nonzero[info->coupling_ang[i]]){ + nonzero[info->coupling_mag[i]]=1; + nonzero[info->coupling_ang[i]]=1; } } @@ -158,26 +224,27 @@ for(i=0;isubmaps;i++){ int ch_in_bundle=0; for(j=0;jchannels;j++){ - if(!info->chmuxlist || info->chmuxlist[j]==i){ + if(info->chmuxlist[j]==i){ if(nonzero[j]) zerobundle[ch_in_bundle]=1; else zerobundle[ch_in_bundle]=0; - pcmbundle[ch_in_bundle++]=vd->work[j]; + pcmbundle[ch_in_bundle++]=vb->pcm[j]; } } - res_inverse(vd,ci->residue_param+info->submaplist[i].residue, - pcmbundle,zerobundle,ch_in_bundle); + look->residue_func[i]->inverse(vb,look->residue_look[i], + pcmbundle,zerobundle,ch_in_bundle); } //for(j=0;jchannels;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=vd->work[info->coupling[i].mag]; - ogg_int32_t *pcmA=vd->work[info->coupling[i].ang]; + ogg_int32_t *pcmM=vb->pcm[info->coupling_mag[i]]; + ogg_int32_t *pcmA=vb->pcm[info->coupling_ang[i]]; for(j=0;jchannels;i++){ - 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); - } + 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); } //for(j=0;jchannels;j++) @@ -229,12 +285,38 @@ /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */ /* only MDCT right now.... */ - for(i=0;ichannels;i++) - mdct_backward(n,vd->work[i]); + for(i=0;ichannels;i++){ + ogg_int32_t *pcm=vb->pcm[i]; + mdct_backward(n,pcm,pcm); + } //for(j=0;jchannels;j++) //_analysis_output("imdct",seq+j,vb->pcm[j],-24,n,0,0); + /* window the data */ + for(i=0;ichannels;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;jchannels;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 -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/mdct.c --- a/misc/libtremor/tremor/mdct.c Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/mdct.c Sun Oct 28 04:00:07 2012 +0100 @@ -6,14 +6,14 @@ * 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 OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * * 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: mdct.c,v 1.9.6.5 2003/04/29 04:03:27 xiphmont Exp $ + last mod: $Id: mdct.c,v 1.9 2002/10/16 09:17:39 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,62 +33,23 @@ ********************************************************************/ #include "ivorbiscodec.h" -#include "os.h" +#include "codebook.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[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]; + 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]; x[0] = r5 + r3; x[1] = r7 - r1; @@ -103,25 +64,29 @@ /* 16 point butterfly (in place, 4 register) */ STIN void mdct_butterfly_16(DATA_TYPE *x){ - - 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); + + 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(); - 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; + 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); + 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; MB(); mdct_butterfly_8(x); @@ -131,40 +96,48 @@ /* 32 point butterfly (in place, 4 register) */ STIN void mdct_butterfly_32(DATA_TYPE *x){ - REG_TYPE r0, r1, r2, r3; + 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[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] ); + 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[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); + 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(); + + r0 = x[22] - x[ 6]; x[22] += x[ 6]; + r1 = x[ 7] - x[23]; x[23] += x[ 7]; + x[ 6] = r1; x[ 7] = r0; MB(); - 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] ); + 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] ); MB(); - 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; + 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); + 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] ); MB(); mdct_butterfly_16(x); @@ -174,30 +147,87 @@ /* 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 - 4; - DATA_TYPE *x2 = x + (points>>1) - 4; - REG_TYPE r0, r1, r2, r3; + 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[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; + 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; + + 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(Tsincos_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; + }while(Tsincos_lookup0); } @@ -205,14 +235,15 @@ int stages=8-shift; int i,j; - + for(i=0;--stages>0;i++){ for(j=0;j<(1<>i)*j,points>>i,4<<(i+shift)); } - + for(j=0;j>8]|(bitrev[(x&0x0f0)>>4]<<4)|(((int)bitrev[x&0x00f])<<8); } -STIN void mdct_bitreverse(DATA_TYPE *x,int n,int shift){ +STIN void mdct_bitreverse(DATA_TYPE *x,int n,int step,int shift){ + int bit = 0; - DATA_TYPE *w = x+(n>>1); + DATA_TYPE *w0 = x; + DATA_TYPE *w1 = x = w0+(n>>1); + LOOKUP_T *T = (step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1; + LOOKUP_T *Ttop = T+1024; + DATA_TYPE r2; do{ - DATA_TYPE b = bitrev12(bit++); - DATA_TYPE *xx = x + (b>>shift); - REG_TYPE r; - - w -= 2; - - if(w>xx){ + DATA_TYPE r3 = bitrev12(bit++); + DATA_TYPE *x0 = x + ((r3 ^ 0xfff)>>shift) -1; + DATA_TYPE *x1 = x + (r3>>shift); - r = xx[0]; - xx[0] = w[0]; - w[0] = r; - - r = xx[1]; - xx[1] = w[1]; - w[1] = r; - } - }while(w>x); -} + REG_TYPE r0 = x0[0] + x1[0]; + REG_TYPE r1 = x1[1] - x0[1]; -STIN void mdct_step7(DATA_TYPE *x,int n,int step){ - DATA_TYPE *w0 = x; - DATA_TYPE *w1 = x+(n>>1); - LOOKUP_T *T = (step>=4)?(sincos_lookup0+(step>>1)):sincos_lookup1; - LOOKUP_T *Ttop = T+1024; - REG_TYPE r0, r1, r2, r3; - - do{ - w1 -= 2; + XPROD32( r0, r1, T[1], T[0], &r2, &r3 ); T+=step; - 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; + w1 -= 4; - r0 = (w0[1] + w1[1])>>1; - r1 = (w0[0] - w1[0])>>1; + r0 = (x0[1] + x1[1])>>1; + r1 = (x0[0] - x1[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 += 2; + w0 += 4; }while(T>shift) -1; + DATA_TYPE *x1 = x + (r3>>shift); + + REG_TYPE r0 = x0[0] + x1[0]; + REG_TYPE r1 = x1[1] - x0[1]; - 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]); + T-=step; XPROD32( r0, r1, T[0], T[1], &r2, &r3 ); - r0 = (w0[1] + w1[1])>>1; - r1 = (w0[0] - w1[0])>>1; + w1 -= 4; + + r0 = (x0[1] + x1[1])>>1; + r1 = (x0[0] - x1[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 += 2; + w0 += 4; }while(w0>1; + int n4=n>>2; + DATA_TYPE *iX; + DATA_TYPE *oX; 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>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>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>1,step); - mdct_butterflies(in,n>>1,shift); - mdct_bitreverse(in,n,shift); - mdct_step7(in,n,step); - mdct_step8(in,n,step); -} + /* rotate */ + + iX = in+n2-7; + oX = out+n2+n4; + T = sincos_lookup0; -void mdct_shift_right(int n, DATA_TYPE *in, DATA_TYPE *right){ - int i; - n>>=2; - in+=1; + 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); - for(i=0;i=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); -void mdct_unroll_lap(int n0,int n1, - int lW,int W, - DATA_TYPE *in, - DATA_TYPE *right, - LOOKUP_T *w0, - LOOKUP_T *w1, - ogg_int16_t *out, - int step, - int start, /* samples, this frame */ - int end /* samples, this frame */){ + mdct_butterflies(out+n2,n2,shift); + mdct_bitreverse(out,n,step,shift); + + /* rotate + window */ + + step>>=2; + { + DATA_TYPE *oX1=out+n2+n4; + DATA_TYPE *oX2=out+n2+n4; + DATA_TYPE *iX =out; - 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 ); + 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>2)-(n0>>2) : 0 ); - int halfLap=(lW && W ? (n1>>2) : (n0>>2) ); - int postLap=(!lW && W ? (n1>>2)-(n0>>2) : 0 ); - int n,off; + 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; - /* preceeding direct-copy lapping from previous frame, if any */ - if(preLap){ - n = (endpost){ - *out = CLIP_TO_15((*--r)>>9); - out+=step; + 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>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(iXpost){ - 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]); - n = (end>9); - out+=step; - l+=2; - } + oX2+=4; + }while(oX2>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); } } diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/mdct.h --- a/misc/libtremor/tremor/mdct.h Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/mdct.h Sun Oct 28 04:00:07 2012 +0100 @@ -6,7 +6,7 @@ * 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 OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * * * ******************************************************************** @@ -34,15 +34,8 @@ #define cPI1_8 (0x7641af3d) #endif -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, - ogg_int16_t *out, - int step, - int start,int end /* samples, this frame */); +extern void mdct_forward(int n, DATA_TYPE *in, DATA_TYPE *out); +extern void mdct_backward(int n, DATA_TYPE *in, DATA_TYPE *out); #endif diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/misc.h --- a/misc/libtremor/tremor/misc.h Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/misc.h Sun Oct 28 04:00:07 2012 +0100 @@ -6,7 +6,7 @@ * 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 OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * * * ******************************************************************** @@ -18,26 +18,10 @@ #ifndef _V_RANDOM_H_ #define _V_RANDOM_H_ #include "ivorbiscodec.h" -#include "os_types.h" - -/*#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 _ogg_malloc -#undef _ogg_calloc -#undef _ogg_realloc -#undef _ogg_free - -#define _ogg_malloc(x) _VDBG_malloc(NULL,(x),__FILE__,__LINE__) -#define _ogg_calloc(x,y) _VDBG_malloc(NULL,(x)*(y),__FILE__,__LINE__) -#define _ogg_realloc(x,y) _VDBG_malloc((x),(y),__FILE__,__LINE__) -#define _ogg_free(x) _VDBG_free((x),__FILE__,__LINE__) -#endif +#include "os.h" #include "asm_arm.h" +#include /* for abs() */ #ifndef _V_WIDE_MATH #define _V_WIDE_MATH @@ -45,7 +29,9 @@ #ifndef _LOW_ACCURACY_ /* 64 bit multiply */ +#if !(defined WIN32 && defined WINCE) #include +#endif #if BYTE_ORDER==LITTLE_ENDIAN union magic { @@ -58,26 +44,26 @@ #endif #if BYTE_ORDER==BIG_ENDIAN -union magic { +/*union magic { struct { ogg_int32_t hi; ogg_int32_t lo; } halves; ogg_int64_t whole; -}; +};*/ #endif -static inline ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { +STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { union magic magic; magic.whole = (ogg_int64_t)x * y; return magic.halves.hi; } -static inline ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { +STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { return MULT32(x,y)<<1; } -static inline ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) { +STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, 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); @@ -99,15 +85,15 @@ * tables in this case. */ -static inline ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { +STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { return (x >> 9) * y; /* y preshifted >>23 */ } -static inline ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { +STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { return (x >> 8) * y; /* y preshifted >>23 */ } -static inline ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) { +STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) { return (x >> 6) * y; /* y preshifted >>9 */ } @@ -144,7 +130,7 @@ #else -static inline void XPROD32(ogg_int32_t a, ogg_int32_t b, +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) { @@ -152,7 +138,7 @@ *y = MULT32(b, t) - MULT32(a, v); } -static inline void XPROD31(ogg_int32_t a, ogg_int32_t b, +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) { @@ -160,7 +146,7 @@ *y = MULT31(b, t) - MULT31(a, v); } -static inline void XNPROD31(ogg_int32_t a, ogg_int32_t b, +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) { @@ -175,7 +161,7 @@ #ifndef _V_CLIP_MATH #define _V_CLIP_MATH -static inline ogg_int32_t CLIP_TO_15(ogg_int32_t x) { +STIN ogg_int32_t CLIP_TO_15(ogg_int32_t x) { int ret=x; ret-= ((x<=32767)-1)&(x-32767); ret-= ((x>=-32768)-1)&(x+32768); @@ -184,6 +170,73 @@ #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 -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/os.h --- a/misc/libtremor/tremor/os.h Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/os.h Sun Oct 28 04:00:07 2012 +0100 @@ -41,6 +41,8 @@ # 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 -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/os_types.h --- a/misc/libtremor/tremor/os_types.h Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/os_types.h Sun Oct 28 04:00:07 2012 +0100 @@ -40,7 +40,6 @@ typedef __int32 ogg_int32_t; typedef unsigned __int32 ogg_uint32_t; typedef __int16 ogg_int16_t; - typedef unsigned __int16 ogg_uint16_t; # else /* Cygwin */ #include <_G_config.h> @@ -48,23 +47,20 @@ typedef _G_int32_t ogg_int32_t; typedef _G_uint32_t ogg_uint32_t; typedef _G_int16_t ogg_int16_t; - typedef _G_uint16_t ogg_uint16_t; # endif #elif defined(__MACOS__) # include typedef SInt16 ogg_int16_t; - typedef UInt16 ogg_uint16_t; typedef SInt32 ogg_int32_t; typedef UInt32 ogg_uint32_t; typedef SInt64 ogg_int64_t; -#elif defined(__MACOSX__) /* MacOS X Framework build */ +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ # include typedef int16_t ogg_int16_t; - typedef u_int16_t ogg_uint16_t; typedef int32_t ogg_int32_t; typedef u_int32_t ogg_uint32_t; typedef int64_t ogg_int64_t; @@ -78,7 +74,6 @@ /* OS/2 GCC */ typedef short ogg_int16_t; - typedef unsigned short ogg_uint16_t; typedef int ogg_int32_t; typedef unsigned int ogg_uint32_t; typedef long long ogg_int64_t; diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/res012.c --- a/misc/libtremor/tremor/res012.c Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/res012.c Sun Oct 28 04:00:07 2012 +0100 @@ -6,7 +6,7 @@ * 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 OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * * * ******************************************************************** @@ -21,15 +21,50 @@ #include "ogg.h" #include "ivorbiscodec.h" #include "codec_internal.h" +#include "registry.h" #include "codebook.h" #include "misc.h" #include "os.h" +#include "block.h" -void res_clear_info(vorbis_info_residue *info){ +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; if(info){ - if(info->stagemasks)_ogg_free(info->stagemasks); - if(info->stagebooks)_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;jparts;j++) + if(look->partbooks[j])_ogg_free(look->partbooks[j]); + _ogg_free(look->partbooks); + for(j=0;jpartvals;j++) + _ogg_free(look->decodemap[j]); + _ogg_free(look->decodemap); + + memset(look,0,sizeof(*look)); + _ogg_free(look); } } @@ -42,193 +77,266 @@ 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 */ -int res_unpack(vorbis_info_residue *info, - vorbis_info *vi,oggpack_buffer *opb){ - int j,k; +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)); codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; - memset(info,0,sizeof(*info)); - info->type=oggpack_read(opb,16); - if(info->type>2 || info->type<0)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); - if(info->groupbook>=ci->books)goto errout; - - info->stagemasks=_ogg_malloc(info->partitions*sizeof(*info->stagemasks)); - info->stagebooks=_ogg_malloc(info->partitions*8*sizeof(*info->stagebooks)); for(j=0;jpartitions;j++){ int cascade=oggpack_read(opb,3); if(oggpack_read(opb,1)) cascade|=(oggpack_read(opb,5)<<3); - info->stagemasks[j]=cascade; + info->secondstages[j]=cascade; + + acc+=icount(cascade); } + for(j=0;jbooklist[j]=oggpack_read(opb,8); + + if(info->groupbook>=ci->books)goto errout; + for(j=0;jbooklist[j]>=ci->books)goto errout; + + return(info); + errout: + res0_free_info(info); + return(NULL); +} + +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)); + codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup; - for(j=0;jpartitions;j++){ - for(k=0;k<8;k++){ - if((info->stagemasks[j]>>k)&1){ - unsigned char book=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; + 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;jparts;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;ksecondstages[j]&(1<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 + } } } - if(oggpack_eop(opb))goto errout; + look->partvals=look->parts; + for(j=1;jpartvals*=look->parts; + look->stages=maxstage; + look->decodemap=(int **)_ogg_malloc(look->partvals*sizeof(*look->decodemap)); + for(j=0;jpartvals;j++){ + long val=j; + long mult=look->partvals/look->parts; + look->decodemap[j]=(int *)_ogg_malloc(dim*sizeof(*look->decodemap[j])); + for(k=0;kparts; + look->decodemap[j][k]=deco; + } + } - return 0; - errout: - res_clear_info(info); - return 1; + return(look); } -int res_inverse(vorbis_dsp_state *vd,vorbis_info_residue *info, - 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; - codebook *phrasebook=ci->book_param+info->groupbook; + +/* 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 */ int samples_per_partition=info->grouping; - int partitions_per_word=phrasebook->dim; - int pcmend=ci->blocksizes[vd->W]; + int partitions_per_word=look->phrasebook->dim; + int max=vb->pcmend>>1; + int end=(info->endend:max); + int n=end-info->begin; - if(info->type<2){ - int max=pcmend>>1; - int end=(info->endend:max); - int n=end-info->begin; + 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;j0){ - int partvals=n/samples_per_partition; - int partwords=(partvals+partitions_per_word-1)/partitions_per_word; + for(s=0;sstages;s++){ - for(i=0;iphrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[j][l]=look->decodemap[temp]; + if(partword[j][l]==NULL)goto errout; + } + } - char **partword=(char **)alloca(ch*sizeof(*partword)); - for(j=0;jstages;s++){ - - for(i=0;i=0;k--) - partword[0][i+k]=partword[0][i+k+1]*info->partitions; - - for(j=1;j=0;k--) - partword[j][i+k]=partword[j-1][i+k]; - - for(j=0;jopb); - if(oggpack_eop(&vd->opb))goto eopbreak; - - /* this can be done quickly in assembly due to the quotient - always being at most six bits */ - for(k=0;kbegin+i*samples_per_partition; + if(info->secondstages[partword[j][l][k]]&(1<partbooks[partword[j][l][k]][s]; + if(stagebook){ + if(decodepart(stagebook,in[j]+offset,&vb->opb, + samples_per_partition,-8)==-1)goto eopbreak; } } - - /* now we decode residual values for the partitions */ - for(k=0;kbegin+i*samples_per_partition; - if(info->stagemasks[partword[j][i]]&(1<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; - } - } - } } - } - } - } - }else{ - int max=(pcmend*ch)>>1; - int end=(info->endend:max); - int n=end-info->begin; - - 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;istages;s++){ - for(i=0;i=0;k--) - partword[i+k]=partword[i+k+1]*info->partitions; - - /* 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;kstagemasks[partword[i]]&(1<book_param+ - info->stagebooks[(partword[i]<<3)+s]; - if(vorbis_book_decodevv_add(stagebook,in, - i*samples_per_partition+beginoff,ch, - &vd->opb, - samples_per_partition,-8)==-1) - goto eopbreak; - } - } - } } } } errout: eopbreak: - - return 0; -} + 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;iinfo; + + /* 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->endend:max); + int n=end-info->begin; + if(n>0){ + + 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;istages;s++){ + for(i=0,l=0;iphrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[l]=look->decodemap[temp]; + if(partword[l]==NULL)goto errout; + } + + /* now we decode residual values for the partitions */ + for(k=0;ksecondstages[partword[l][k]]&(1<partbooks[partword[l][k]][s]; + + if(stagebook){ + if(vorbis_book_decodevv_add(stagebook,in, + i*samples_per_partition+beginoff,ch, + &vb->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 +}; + +vorbis_func_residue residue2_exportbundle={ + &res0_unpack, + &res0_look, + &res0_free_info, + &res0_free_look, + &res2_inverse +}; diff -r 775a72905708 -r a12155461b34 misc/libtremor/tremor/vorbisfile.c --- a/misc/libtremor/tremor/vorbisfile.c Sun Oct 28 03:48:37 2012 +0100 +++ b/misc/libtremor/tremor/vorbisfile.c Sun Oct 28 04:00:07 2012 +0100 @@ -12,7 +12,7 @@ ******************************************************************** function: stdio-based convenience library for opening/seeking/decoding - last mod: $Id: vorbisfile.c,v 1.6.2.4 2003/04/29 04:03:27 xiphmont Exp $ + last mod: $Id: vorbisfile.c,v 1.6 2003/03/30 23:40:56 xiphmont Exp $ ********************************************************************/ @@ -22,19 +22,11 @@ #include #include -#include "codec_internal.h" +#include "ivorbiscodec.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 @@ -72,10 +64,10 @@ unsigned char *buffer=ogg_sync_bufferin(vf->oy,CHUNKSIZE); long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource); if(bytes>0)ogg_sync_wrote(vf->oy,bytes); - if(bytes==0 && errno)return -1; - return 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 */ @@ -111,7 +103,7 @@ while(1){ long more; - if(boundary>0 && vf->offset>=boundary)return OV_FALSE; + if(boundary>0 && vf->offset>=boundary)return(OV_FALSE); more=ogg_sync_pageseek(vf->oy,og); if(more<0){ @@ -120,18 +112,18 @@ }else{ if(more==0){ /* send more paramedics */ - if(!boundary)return OV_FALSE; + if(!boundary)return(OV_FALSE); { long ret=_get_data(vf); - if(ret==0)return OV_EOF; - if(ret<0)return OV_EREAD; + if(ret==0)return(OV_EOF); + if(ret<0)return(OV_EREAD); } }else{ /* 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; + return(ret); } } @@ -157,7 +149,7 @@ _seek_helper(vf,begin); while(vf->offsetoffset); - if(ret==OV_EREAD)return OV_EREAD; + if(ret==OV_EREAD)return(OV_EREAD); if(ret<0){ break; }else{ @@ -171,9 +163,9 @@ ret=_get_next_page(vf,og,CHUNKSIZE); if(ret<0) /* this shouldn't be possible */ - return OV_EFAULT; + return(OV_EFAULT); - return offset; + return(offset); } /* finds each bitstream link one at a time using a bisection search @@ -204,7 +196,7 @@ _seek_helper(vf,bisect); ret=_get_next_page(vf,&og,-1); - if(ret==OV_EREAD)return OV_EREAD; + if(ret==OV_EREAD)return(OV_EREAD); if(ret<0 || ogg_page_serialno(&og)!=currentno){ endsearched=bisect; if(ret>=0)next=ret; @@ -216,7 +208,7 @@ _seek_helper(vf,next); ret=_get_next_page(vf,&og,-1); - if(ret==OV_EREAD)return OV_EREAD; + if(ret==OV_EREAD)return(OV_EREAD); if(searched>=end || ret<0){ ogg_page_release(&og); @@ -228,33 +220,17 @@ ret=_bisect_forward_serialno(vf,next,vf->offset, end,ogg_page_serialno(&og),m+1); ogg_page_release(&og); - if(ret==OV_EREAD)return OV_EREAD; + if(ret==OV_EREAD)return(OV_EREAD); } vf->offsets[m]=begin; vf->serialnos[m]=currentno; - return 0; -} - -static int _decode_clear(OggVorbis_File *vf){ - if(vf->ready_state==INITSET){ - vorbis_dsp_destroy(vf->vd); - vf->vd=0; - vf->ready_state=STREAMSET; - } - - if(vf->ready_state>=STREAMSET){ - vorbis_info_clear(&vf->vi); - vorbis_comment_clear(&vf->vc); - vf->ready_state=OPENED; - } - return 0; + return(0); } /* uses the local ogg_stream storage in vf; this is important for non-streaming input sources */ /* consumes the page that's passed in (if any) */ -/* state is LINKSET upon successful return */ static int _fetch_headers(OggVorbis_File *vf, vorbis_info *vi, @@ -265,17 +241,16 @@ ogg_packet op={0,0,0,0,0,0}; int i,ret; - 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==OV_EREAD)return(OV_EREAD); if(llret<0)return OV_ENOTVORBIS; og_ptr=&og; } ogg_stream_reset_serialno(vf->os,ogg_page_serialno(og_ptr)); if(serialno)*serialno=vf->os->serialno; + vf->ready_state=STREAMSET; /* extract the initial header from the first page and verify that the Ogg bitstream is in fact Vorbis data */ @@ -293,7 +268,7 @@ ret=OV_EBADHEADER; goto bail_header; } - if((ret=vorbis_dsp_headerin(vi,vc,&op))){ + if((ret=vorbis_synthesis_headerin(vi,vc,&op))){ goto bail_header; } i++; @@ -307,7 +282,6 @@ ogg_packet_release(&op); ogg_page_release(&og); - vf->ready_state=LINKSET; return 0; bail_header: @@ -320,45 +294,22 @@ return ret; } -/* 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(OggVorbis_File *vf,int link){ - if(link != vf->current_link) _decode_clear(vf); - if(vf->ready_stateoffsets[link]); - 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); - } - return 0; -} - -static int _set_link_number_preserve_pos(OggVorbis_File *vf,int link){ - ogg_int64_t pos=vf->offset; - int ret=_set_link_number(vf,link); - if(ret)return ret; - _seek_helper(vf,pos); - if(posoffsets[link] || pos>=vf->offsets[link+1]) - vf->ready_state=STREAMSET; - return 0; -} - -/* last step of the OggVorbis_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) */ +/* last step of the OggVorbis_File initialization; get all the + vorbis_info structs and PCM positions. Only called by the seekable + initialization (local stream storage is hacked slightly; pay + attention to how that's done) */ /* 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 OggVorbis_File struct */ -static void _prefetch_all_offsets(OggVorbis_File *vf, ogg_int64_t dataoffset){ +static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){ ogg_page og={0,0,0,0}; int i; ogg_int64_t ret; + vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi)); + vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc)); vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets)); vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths)); @@ -373,7 +324,7 @@ /* seek to the location of the initial header */ _seek_helper(vf,vf->offsets[i]); - if(_fetch_headers(vf,&vf->vi,&vf->vc,NULL,NULL)<0){ + if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){ vf->dataoffsets[i]=-1; }else{ vf->dataoffsets[i]=vf->offset; @@ -407,7 +358,7 @@ ogg_stream_pagein(vf->os,&og); while((result=ogg_stream_packetout(vf->os,&op))){ if(result>0){ /* ignore holes */ - long thisblock=vorbis_packet_blocksize(&vf->vi,&op); + long thisblock=vorbis_packet_blocksize(vf->vi+i,&op); if(lastblock!=-1) accumulated+=(lastblock+thisblock)>>2; lastblock=thisblock; @@ -439,8 +390,8 @@ ret=_get_prev_page(vf,&og); if(ret<0){ /* this should not be possible */ - vorbis_info_clear(&vf->vi); - vorbis_comment_clear(&vf->vc); + vorbis_info_clear(vf->vi+i); + vorbis_comment_clear(vf->vc+i); break; } if(ogg_page_granulepos(&og)!=-1){ @@ -454,28 +405,18 @@ ogg_page_release(&og); } -static int _make_decode_ready(OggVorbis_File *vf){ - int i; - switch(vf->ready_state){ - case OPENED: - case STREAMSET: - for(i=0;ilinks;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; - } - +static void _make_decode_ready(OggVorbis_File *vf){ + if(vf->ready_state!=STREAMSET)return; + if(vf->seekable){ + vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link); + }else{ + vorbis_synthesis_init(&vf->vd,vf->vi); + } + vorbis_block_init(&vf->vd,&vf->vb); + vf->ready_state=INITSET; + vf->bittrack=0; + vf->samptrack=0; + return; } static int _open_seekable2(OggVorbis_File *vf){ @@ -493,7 +434,7 @@ /* We get the offset for the last page of the physical bitstream. Most OggVorbis files will contain a single logical bitstream */ end=_get_prev_page(vf,&og); - if(end<0)return end; + if(end<0)return(end); /* more than one logical bitstream? */ tempserialno=ogg_page_serialno(&og); @@ -503,18 +444,25 @@ /* 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; + if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD); }else{ /* Only one logical bitstream */ - if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return OV_EREAD; + if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD); } /* the initial header memory is referenced by vf after; don't free it */ - _prefetch_all_offsets(vf,dataoffset); - return ov_raw_seek(vf,0); + _prefetch_all_headers(vf,dataoffset); + return(ov_raw_seek(vf,0)); +} + +/* 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; } /* fetch and process a packet. Handles the case where we're at a @@ -553,16 +501,28 @@ if(result>0){ /* got a packet. process it */ granulepos=op.granulepos; - if(!vorbis_dsp_synthesis(vf->vd,&op,1)){ /* lazy check for lazy + if(!vorbis_synthesis(&vf->vb,&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; + + /* 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){ + ret=OV_EFAULT; + goto cleanup; + } + + vorbis_synthesis_blockin(&vf->vd,&vf->vb); + vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples; + vf->bittrack+=op.bytes*8; + } /* update the pcm offset. */ if(granulepos!=-1 && !op.e_o_s){ @@ -589,7 +549,7 @@ here unless the stream is very broken */ - samples=vorbis_dsp_pcmout(vf->vd,NULL,0); + samples=vorbis_synthesis_pcmout(&vf->vd,NULL); granulepos-=samples; for(i=0;iseekable){ + vorbis_info_clear(vf->vi); + vorbis_comment_clear(vf->vc); + } } } } @@ -646,7 +611,7 @@ */ if(vf->ready_state!=INITSET){ - int link,ret; + int link; if(vf->ready_stateseekable){ @@ -662,22 +627,24 @@ 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; + + 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,&vf->current_serialno,&og); + int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og); if(ret) goto cleanup; vf->current_link++; + link=0; } } - if(_make_decode_ready(vf)) return OV_EBADLINK; + _make_decode_ready(vf); } ogg_stream_pagein(vf->os,&og); } @@ -690,7 +657,7 @@ /* 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; + if(f==NULL)return(-1); return fseek(f,off,whence); } @@ -700,11 +667,6 @@ 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; @@ -727,15 +689,17 @@ /* 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)); vf->os=ogg_stream_create(-1); /* fill in the serialno later */ /* Try to fetch the headers, maintaining all the storage */ - if((ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL))<0){ + if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){ vf->datasource=NULL; ov_clear(vf); }else if(vf->ready_state < PARTOPEN) vf->ready_state=PARTOPEN; - return ret; + return(ret); } static int _ov_open2(OggVorbis_File *vf){ @@ -747,7 +711,7 @@ vf->datasource=NULL; ov_clear(vf); } - return ret; + return(ret); } return 0; } @@ -756,24 +720,33 @@ /* clear out the OggVorbis_File struct */ int ov_clear(OggVorbis_File *vf){ if(vf){ - vorbis_dsp_destroy(vf->vd); - vf->vd=0; + vorbis_block_clear(&vf->vb); + vorbis_dsp_clear(&vf->vd); ogg_stream_destroy(vf->os); - vorbis_info_clear(&vf->vi); - vorbis_comment_clear(&vf->vc); + + if(vf->vi && vf->links){ + int i; + for(i=0;ilinks;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_destroy(vf->oy); - if(vf->datasource)(vf->callbacks.close_func)(vf->datasource); + if(vf->datasource && vf->callbacks.close_func) + (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 @@ -825,7 +798,7 @@ } int ov_test_open(OggVorbis_File *vf){ - if(vf->ready_state!=PARTOPEN)return OV_EINVAL; + if(vf->ready_state!=PARTOPEN)return(OV_EINVAL); return _ov_open2(vf); } @@ -849,9 +822,9 @@ vorbis_info structs */ long ov_bitrate(OggVorbis_File *vf,int i){ - if(vf->ready_state=vf->links)return OV_EINVAL; - if(!vf->seekable && i!=0)return ov_bitrate(vf,0); + if(vf->ready_state=vf->links)return(OV_EINVAL); + if(!vf->seekable && i!=0)return(ov_bitrate(vf,0)); if(i<0){ ogg_int64_t bits=0; int i; @@ -861,24 +834,24 @@ * 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.bitrate_nominal>0){ - return vf->vi.bitrate_nominal; + if(vf->vi[i].bitrate_nominal>0){ + return vf->vi[i].bitrate_nominal; }else{ - if(vf->vi.bitrate_upper>0){ - if(vf->vi.bitrate_lower>0){ - return (vf->vi.bitrate_upper+vf->vi.bitrate_lower)/2; + 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.bitrate_upper; + return vf->vi[i].bitrate_upper; } } - return OV_FALSE; + return(OV_FALSE); } } } @@ -889,23 +862,24 @@ EINVAL if stream is only partially open */ long ov_bitrate_instant(OggVorbis_File *vf){ + int link=(vf->seekable?vf->current_link:0); long ret; - if(vf->ready_statesamptrack==0)return OV_FALSE; - ret=vf->bittrack/vf->samptrack*vf->vi.rate; + if(vf->ready_statesamptrack==0)return(OV_FALSE); + ret=vf->bittrack/vf->samptrack*vf->vi[link].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); + 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]); } } @@ -915,16 +889,16 @@ or if stream is only partially open */ ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){ - if(vf->ready_stateseekable || i>=vf->links)return OV_EINVAL; + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); if(i<0){ ogg_int64_t acc=0; int i; for(i=0;ilinks;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]); } } @@ -934,16 +908,16 @@ length) or only partially open */ ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){ - if(vf->ready_stateseekable || i>=vf->links)return OV_EINVAL; + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); if(i<0){ ogg_int64_t acc=0; int i; for(i=0;ilinks;i++) acc+=ov_pcm_total(vf,i); - return acc; + return(acc); }else{ - return vf->pcmlengths[i*2+1]; + return(vf->pcmlengths[i*2+1]); } } @@ -953,16 +927,16 @@ length) or only partially open */ ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){ - if(vf->ready_stateseekable || i>=vf->links)return OV_EINVAL; + if(vf->ready_stateseekable || i>=vf->links)return(OV_EINVAL); if(i<0){ ogg_int64_t acc=0; int i; for(i=0;ilinks;i++) acc+=ov_time_total(vf,i); - return acc; + return(acc); }else{ - return ((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi.rate; + return(((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi[i].rate); } } @@ -978,11 +952,11 @@ ogg_page og={0,0,0,0}; ogg_packet op={0,0,0,0,0,0}; - if(vf->ready_stateready_stateseekable) - return OV_ENOSEEK; /* don't dump machine if we can't seek */ + return(OV_ENOSEEK); /* don't dump machine if we can't seek */ - if(pos<0 || pos>vf->end)return OV_EINVAL; + 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 @@ -991,7 +965,7 @@ vf->pcm_offset=-1; ogg_stream_reset_serialno(vf->os, vf->current_serialno); /* must set serialno */ - vorbis_dsp_restart(vf->vd); + vorbis_synthesis_restart(&vf->vd); _seek_helper(vf,pos); @@ -1014,7 +988,7 @@ int lastblock=0; int accblock=0; int thisblock; - int eosflag; + int eosflag=0; work_os=ogg_stream_create(vf->current_serialno); /* get the memory ready */ while(1){ @@ -1024,8 +998,8 @@ if(result>0){ - if(vf->vi.codec_setup){ - thisblock=vorbis_packet_blocksize(&vf->vi,&op); + 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; @@ -1065,7 +1039,7 @@ break; } - /* did we just grab a page from other than current link? */ + /* has our decoding just traversed a bitstream boundary? */ if(vf->ready_state>=STREAMSET) if(vf->current_serialno!=ogg_page_serialno(&og)){ _decode_clear(vf); /* clear out stream state */ @@ -1082,14 +1056,11 @@ 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; - } + vf->current_link=link; + ogg_stream_reset_serialno(vf->os,vf->current_serialno); ogg_stream_reset_serialno(work_os,vf->current_serialno); - + vf->ready_state=STREAMSET; } @@ -1108,7 +1079,7 @@ ogg_stream_destroy(work_os); vf->bittrack=0; vf->samptrack=0; - return 0; + return(0); seek_error: ogg_packet_release(&op); @@ -1134,9 +1105,9 @@ ogg_page og={0,0,0,0}; ogg_packet op={0,0,0,0,0,0}; - if(vf->ready_stateseekable)return OV_ENOSEEK; - if(pos<0 || pos>total)return OV_EINVAL; + if(vf->ready_stateseekable)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--){ @@ -1144,16 +1115,6 @@ if(pos>=total)break; } - - if(link!=vf->current_link){ - int ret=_set_link_number(vf,link); - if(ret) goto seek_error; - }else{ - vorbis_dsp_restart(vf->vd); - } - - ogg_stream_reset_serialno(vf->os,vf->serialnos[link]); - /* 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 @@ -1236,9 +1197,22 @@ if(_get_next_page(vf,&og,-1)<0){ ogg_page_release(&og); - return OV_EOF; /* shouldn't happen */ + return(OV_EOF); /* shouldn't happen */ } + if(link!=vf->current_link){ + /* Different link; dump entire decode machine */ + _decode_clear(vf); + + vf->current_link=link; + vf->current_serialno=ogg_page_serialno(&og); + 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); /* pull out all but last packet; the one with granulepos */ @@ -1287,7 +1261,7 @@ ogg_page_release(&og); ogg_packet_release(&op); - return 0; + return(0); seek_error: @@ -1308,8 +1282,8 @@ 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(_make_decode_ready(vf))return OV_EBADLINK; + if(ret<0)return(ret); + _make_decode_ready(vf); /* discard leading packets we don't need for the lapping of the position we want; don't decode them */ @@ -1318,7 +1292,7 @@ int ret=ogg_stream_packetpeek(vf->os,&op); if(ret>0){ - thisblock=vorbis_packet_blocksize(&vf->vi,&op); + thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); if(thisblock<0){ ogg_stream_packetout(vf->os,NULL); continue; /* non audio packet */ @@ -1326,13 +1300,14 @@ 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_dsp_synthesis(vf->vd,&op,0); /* set up a vb with - only tracking, no - pcm_decode */ + vorbis_synthesis(&vf->vb,&op,0); /* set up a vb with + only tracking, no + pcm_decode */ + vorbis_synthesis_blockin(&vf->vd,&vf->vb); /* end of logical stream case is hard, especially with exact length positioning. */ @@ -1356,7 +1331,7 @@ if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf); if(vf->ready_statecurrent_serialno=ogg_page_serialno(&og); for(link=0;linklinks;link++) @@ -1364,14 +1339,13 @@ if(link==vf->links){ ogg_page_release(&og); ogg_packet_release(&op); - return OV_EBADLINK; + 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; + + ogg_stream_reset_serialno(vf->os,vf->current_serialno); + vf->ready_state=STREAMSET; + _make_decode_ready(vf); lastblock=0; } @@ -1385,10 +1359,10 @@ logical bitstream boundary with abandon is OK. */ while(vf->pcm_offsetpcm_offset; - long samples=vorbis_dsp_pcmout(vf->vd,NULL,0); + long samples=vorbis_synthesis_pcmout(&vf->vd,NULL); if(samples>target)samples=target; - vorbis_dsp_read(vf->vd,samples); + vorbis_synthesis_read(&vf->vd,samples); vf->pcm_offset+=samples; if(samplesready_stateseekable)return OV_ENOSEEK; - if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL; + if(vf->ready_stateseekable)return(OV_ENOSEEK); + if(milliseconds<0 || milliseconds>time_total)return(OV_EINVAL); /* which bitstream section does this time offset occur in? */ for(link=vf->links-1;link>=0;link--){ @@ -1423,11 +1397,8 @@ /* enough information to convert time offset to pcm offset */ { - 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); + ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000; + return(ov_pcm_seek(vf,target)); } } @@ -1440,9 +1411,9 @@ ogg_int64_t pcm_total=ov_pcm_total(vf,-1); ogg_int64_t time_total=ov_time_total(vf,-1); - if(vf->ready_stateseekable)return OV_ENOSEEK; - if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL; + if(vf->ready_stateseekable)return(OV_ENOSEEK); + if(milliseconds<0 || milliseconds>time_total)return(OV_EINVAL); /* which bitstream section does this time offset occur in? */ for(link=vf->links-1;link>=0;link--){ @@ -1453,25 +1424,22 @@ /* enough information to convert time offset to pcm offset */ { - 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); + ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000; + return(ov_pcm_seek_page(vf,target)); } } /* 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_stateoffset; + if(vf->ready_stateoffset); } /* return PCM offset (sample) of next PCM sample to be read */ ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){ - if(vf->ready_statepcm_offset; + if(vf->ready_statepcm_offset); } /* return time offset (milliseconds) of next PCM sample to be read */ @@ -1480,7 +1448,7 @@ ogg_int64_t pcm_total=0; ogg_int64_t time_total=0; - if(vf->ready_stateready_stateseekable){ pcm_total=ov_pcm_total(vf,-1); time_total=ov_time_total(vf,-1); @@ -1493,7 +1461,7 @@ } } - return time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi.rate; + return(time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi[link].rate); } /* link: -1) return the vorbis_info struct for the bitstream section @@ -1506,25 +1474,37 @@ vorbis_info *ov_info(OggVorbis_File *vf,int link){ if(vf->seekable){ - if(link>=vf->links)return NULL; - if(link>=0){ - int ret=_set_link_number_preserve_pos(vf,link); - if(ret)return NULL; - } + 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; } - return &vf->vi; } /* grr, strong typing, grr, no templates/inheritence, grr */ vorbis_comment *ov_comment(OggVorbis_File *vf,int link){ if(vf->seekable){ - if(link>=vf->links)return NULL; - if(link>=0){ - int ret=_set_link_number_preserve_pos(vf,link); - if(ret)return NULL; - } + 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; } - return &vf->vc; } /* up to this point, everything could more or less hide the multiple @@ -1554,36 +1534,54 @@ *section) set to the logical bitstream number */ -long ov_read(OggVorbis_File *vf,void *buffer,int bytes_req,int *bitstream){ +long ov_read(OggVorbis_File *vf,char *buffer,int bytes_req,int *bitstream){ + int i,j; + ogg_int32_t **pcm; long samples; - long channels; - if(vf->ready_stateready_stateready_state==INITSET){ - 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; - } + samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); + if(samples)break; } /* suck in another packet */ { 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>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); + } }