summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2000-12-27 23:46:38 +0000
committerMonty <xiphmont@xiph.org>2000-12-27 23:46:38 +0000
commit6f5ce779237ca696ea44f7b24671baeb042235b9 (patch)
tree3a10a10377ee9c656e1136939ada24fecfb0eec7
downloadlibvorbis-git-6f5ce779237ca696ea44f7b24671baeb042235b9.tar.gz
Major work on psy.c
some global optimization (less memory and lin->dB->lin conversions) median based noise curve FFT based tone masking *much* faster encode. We still have a bug where current tuning overflows codebooks on the 100dB masking curves. Hacked around for now. Monty svn path=/branches/monty_branch_20001226/vorbis/; revision=1131
-rw-r--r--configure.in169
-rwxr-xr-xdebian/rules77
-rw-r--r--examples/encoder_example.c199
-rw-r--r--include/vorbis/codec.h225
-rw-r--r--lib/analysis.c107
-rw-r--r--lib/backends.h148
-rw-r--r--lib/block.c780
-rw-r--r--lib/codec_internal.h117
-rw-r--r--lib/envelope.c233
-rw-r--r--lib/floor0.c430
-rw-r--r--lib/info.c571
-rw-r--r--lib/mapping0.c441
-rw-r--r--lib/modes/mode_A.h300
-rw-r--r--lib/modes/mode_AA.h292
-rw-r--r--lib/modes/mode_B.h210
-rw-r--r--lib/modes/mode_C.h283
-rw-r--r--lib/modes/mode_D.h236
-rw-r--r--lib/modes/mode_E.h169
-rw-r--r--lib/psy.c654
-rw-r--r--lib/psy.h103
-rw-r--r--lib/psytune.c392
-rw-r--r--lib/scales.h51
-rw-r--r--libvorbis.spec84
23 files changed, 6271 insertions, 0 deletions
diff --git a/configure.in b/configure.in
new file mode 100644
index 00000000..e1fac805
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,169 @@
+dnl Process this file with autoconf to produce a configure script
+
+dnl ------------------------------------------------
+dnl Initialization and Versioning
+dnl ------------------------------------------------
+
+AC_INIT(lib/mdct.c)
+AM_INIT_AUTOMAKE(libvorbis,1.0prebeta4)
+
+dnl Library versioning
+
+V_LIB_CURRENT=0
+V_LIB_REVISION=0
+V_LIB_AGE=0
+VF_LIB_CURRENT=0
+VF_LIB_REVISION=0
+VF_LIB_AGE=0
+VE_LIB_CURRENT=0
+VE_LIB_REVISION=0
+VE_LIB_AGE=0
+AC_SUBST(V_LIB_CURRENT)
+AC_SUBST(V_LIB_REVISION)
+AC_SUBST(V_LIB_AGE)
+AC_SUBST(VF_LIB_CURRENT)
+AC_SUBST(VF_LIB_REVISION)
+AC_SUBST(VF_LIB_AGE)
+AC_SUBST(VE_LIB_CURRENT)
+AC_SUBST(VE_LIB_REVISION)
+AC_SUBST(VE_LIB_AGE)
+
+dnl --------------------------------------------------
+dnl Check for programs
+dnl --------------------------------------------------
+
+dnl save $CFLAGS since AC_PROG_CC likes to insert "-g -O2"
+dnl if $CFLAGS is blank
+cflags_save="$CFLAGS"
+AC_PROG_CC
+CFLAGS="$cflags_save"
+
+AM_PROG_LIBTOOL
+
+dnl --------------------------------------------------
+dnl Set build flags based on environment
+dnl --------------------------------------------------
+
+AC_CANONICAL_HOST
+
+dnl Set some target options
+if test -z "$GCC"; then
+ case $host in
+ *-*-irix*)
+ dnl If we're on IRIX, we wanna use cc even if gcc
+ dnl is there (unless the user has overriden us)...
+ if test -z "$CC"; then
+ CC=cc
+ fi
+ DEBUG="-g -signed"
+ CFLAGS="-O2 -w -signed"
+ PROFILE="-p -g3 -O2 -signed" ;;
+ sparc-sun-solaris*)
+ DEBUG="-v -g"
+ CFLAGS="-xO4 -fast -w -fsimple -native -xcg92"
+ PROFILE="-v -xpg -g -xO4 -fast -native -fsimple -xcg92 -Dsuncc" ;;
+ *)
+ DEBUG="-g"
+ CFLAGS="-O"
+ PROFILE="-g -p" ;;
+ esac
+else
+
+ case $host in
+ *86-*-linux*)
+ DEBUG="-g -Wall -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"
+ CFLAGS="-O20 -ffast-math -mno-ieee-fp -D_REENTRANT -fsigned-char"
+# PROFILE="-Wall -W -pg -g -O20 -ffast-math -D_REENTRANT -fsigned-char -fno-inline -static"
+ PROFILE="-Wall -W -pg -g -O20 -ffast-math -mno-ieee-fp -D_REENTRANT -fsigned-char -fno-inline -static"
+
+ # glibc < 2.1.3 has a serious FP bug in the math inline header
+ # that will cripple Vorbis. Look to see if the magic FP stack
+ # clobber is missing in the mathinline header, thus indicating
+ # the buggy version
+
+ AC_EGREP_CPP(log10.*fldlg2.*fxch,[
+ #define __LIBC_INTERNAL_MATH_INLINES 1
+ #define __OPTIMIZE__
+ #include <math.h>
+ ],bad=maybe,bad=no)
+ if test ${bad} = "maybe" ;then
+ AC_EGREP_CPP(log10.*fldlg2.*fxch.*st\([[0123456789]]*\),
+ [
+ #define __LIBC_INTERNAL_MATH_INLINES 1
+ #define __OPTIMIZE__
+ #include <math.h>
+ ],bad=no,bad=yes)
+ fi
+ if test ${bad} = "yes" ;then
+ AC_MSG_WARN([ ])
+ AC_MSG_WARN([********************************************************])
+ AC_MSG_WARN([* The glibc headers on this machine have a serious bug *])
+ AC_MSG_WARN([* in /usr/include/bits/mathinline.h This bug affects *])
+ AC_MSG_WARN([* all floating point code, not just Ogg, built on this *])
+ AC_MSG_WARN([* machine. Upgrading to glibc 2.1.3 is strongly urged *])
+ AC_MSG_WARN([* to correct the problem. Note that upgrading glibc *])
+ AC_MSG_WARN([* will not fix any previously built programs; this is *])
+ AC_MSG_WARN([* a compile-time time bug. *])
+ AC_MSG_WARN([* To work around the problem for this build of Ogg, *])
+ AC_MSG_WARN([* autoconf is disabling all math inlining. This will *])
+ AC_MSG_WARN([* hurt Ogg performace but is necessary for an Ogg that *])
+ AC_MSG_WARN([* will actually work. Once glibc is upgraded, rerun *])
+ AC_MSG_WARN([* configure and make to build with inlining. *])
+ AC_MSG_WARN([********************************************************])
+ AC_MSG_WARN([ ])
+
+ CFLAGS=${OPT}" -D__NO_MATH_INLINES"
+ PROFILE=${PROFILE}" -D__NO_MATH_INLINES"
+ fi;;
+ *-*-linux*)
+ DEBUG="-g -Wall -D_REENTRANT -D__NO_MATH_INLINES -fsigned-char"
+ CFLAGS="-O20 -ffast-math -D_REENTRANT -fsigned-char"
+ PROFILE="-pg -g -O20 -ffast-math -D_REENTRANT -fsigned-char";;
+ sparc-sun-*)
+ DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char -mv8"
+ CFLAGS="-O20 -ffast-math -D__NO_MATH_INLINES -fsigned-char -mv8"
+ PROFILE="-pg -g -O20 -D__NO_MATH_INLINES -fsigned-char -mv8" ;;
+ *)
+ DEBUG="-g -Wall -D__NO_MATH_INLINES -fsigned-char"
+ CFLAGS="-O20 -D__NO_MATH_INLINES -fsigned-char"
+ PROFILE="-O20 -g -pg -D__NO_MATH_INLINES -fsigned-char" ;;
+ esac
+fi
+
+dnl --------------------------------------------------
+dnl Check for headers
+dnl --------------------------------------------------
+
+AC_CHECK_HEADER(memory.h,CFLAGS="$CFLAGS -DUSE_MEMORY_H",:)
+
+dnl --------------------------------------------------
+dnl Check for typedefs, structures, etc
+dnl --------------------------------------------------
+
+dnl none
+
+dnl --------------------------------------------------
+dnl Check for libraries
+dnl --------------------------------------------------
+
+AC_CHECK_LIB(m, cos, LIBS="-lm", LIBS="")
+AC_CHECK_LIB(pthread, pthread_create, pthread_lib="-lpthread", :)
+
+AM_PATH_OGG(LIBS="$LIBS $OGG_LIBS", AC_MSG_ERROR(must have Ogg installed!))
+
+dnl --------------------------------------------------
+dnl Check for library functions
+dnl --------------------------------------------------
+
+AC_FUNC_ALLOCA
+AC_FUNC_MEMCMP
+
+dnl --------------------------------------------------
+dnl Do substitutions
+dnl --------------------------------------------------
+
+AC_SUBST(DEBUG)
+AC_SUBST(PROFILE)
+AC_SUBST(pthread_lib)
+
+AC_OUTPUT(Makefile lib/Makefile lib/modes/Makefile lib/books/Makefile doc/Makefile doc/vorbisfile/Makefile doc/vorbisenc/Makefile include/Makefile include/vorbis/Makefile examples/Makefile win32/Makefile debian/Makefile vq/Makefile)
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 00000000..9937d63f
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,77 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# This is the debhelper compatability version to use.
+export DH_COMPAT=2
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ # Add here commands to configure the package.
+
+ # If compiling cvs version change to ./autogen.sh --prefix=/usr
+ ./configure --prefix=/usr
+
+ touch configure-stamp
+
+build: configure-stamp build-stamp
+build-stamp:
+ dh_testdir
+
+ # Add here commands to compile the package.
+ $(MAKE)
+
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+
+ # Add here commands to clean up after the build process.
+ -$(MAKE) clean
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/tmp.
+ $(MAKE) install DESTDIR=`pwd`/debian/tmp
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+
+ dh_movefiles
+
+ dh_installdocs debian/tmp/usr/share/doc/libvorbis-1.0prebeta4/*
+ dh_installexamples
+ dh_installmanpages
+ dh_installchangelogs
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/examples/encoder_example.c b/examples/encoder_example.c
new file mode 100644
index 00000000..cb5da7df
--- /dev/null
+++ b/examples/encoder_example.c
@@ -0,0 +1,199 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: simple example encoder
+ last mod: $Id: encoder_example.c,v 1.17.2.1 2000/12/27 23:46:33 xiphmont Exp $
+
+ ********************************************************************/
+
+/* takes a stereo 16bit 44.1kHz WAV file from stdin and encodes it into
+ a Vorbis bitstream */
+
+/* Note that this is POSIX, not ANSI, code */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+#include <vorbis/vorbisenc.h>
+
+#ifdef _WIN32 /* We need the following two to set stdin/stdout to binary */
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#if defined(macintosh) && defined(__MWERKS__)
+#include <console.h> /* CodeWarrior's Mac "command-line" support */
+#endif
+
+#define READ 1024
+signed char readbuffer[READ*4+44]; /* out of the data segment, not the stack */
+
+int main(){
+ ogg_stream_state os; /* take physical pages, weld into a logical
+ stream of packets */
+ ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
+ ogg_packet op; /* one raw packet of data for decode */
+
+ vorbis_info vi; /* struct that stores all the static vorbis bitstream
+ settings */
+ vorbis_comment vc; /* struct that stores all the user comments */
+
+ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+ vorbis_block vb; /* local working space for packet->PCM decode */
+
+ int eos=0;
+
+#if defined(macintosh) && defined(__MWERKS__)
+ int argc = 0;
+ char **argv = NULL;
+ argc = ccommand(&argv); /* get a "command line" from the Mac user */
+ /* this also lets the user set stdin and stdout */
+#endif
+
+ /* we cheat on the WAV header; we just bypass 44 bytes and never
+ verify that it matches 16bit/stereo/44.1kHz. This is just an
+ example, after all. */
+
+#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
+ /* Beware the evil ifdef. We avoid these where we can, but this one we
+ cannot. Don't add any more, you'll probably go to hell if you do. */
+ _setmode( _fileno( stdin ), _O_BINARY );
+ _setmode( _fileno( stdout ), _O_BINARY );
+#endif
+
+
+ fread(readbuffer,1,44,stdin);
+
+ /********** Encode setup ************/
+
+ /* choose an encoding mode */
+ /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
+ vorbis_info_init(&vi);
+ vorbis_encode_init(&vi,2,44100, -1, 128000, -1);
+
+ /* add a comment */
+ vorbis_comment_init(&vc);
+ vorbis_comment_add(&vc,"Track encoded by encoder_example.c");
+
+ /* set up the analysis state and auxiliary encoding storage */
+ vorbis_analysis_init(&vd,&vi);
+ vorbis_block_init(&vd,&vb);
+
+ /* set up our packet->stream encoder */
+ /* pick a random serial number; that way we can more likely build
+ chained streams just by concatenation */
+ srand(time(NULL));
+ ogg_stream_init(&os,rand());
+
+ /* Vorbis streams begin with three headers; the initial header (with
+ most of the codec setup parameters) which is mandated by the Ogg
+ bitstream spec. The second header holds any comment fields. The
+ third header holds the bitstream codebook. We merely need to
+ make the headers, then pass them to libvorbis one at a time;
+ libvorbis handles the additional Ogg bitstream constraints */
+
+ {
+ ogg_packet header;
+ ogg_packet header_comm;
+ ogg_packet header_code;
+
+ vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
+ ogg_stream_packetin(&os,&header); /* automatically placed in its own
+ page */
+ ogg_stream_packetin(&os,&header_comm);
+ ogg_stream_packetin(&os,&header_code);
+
+ /* We don't have to write out here, but doing so makes streaming
+ * much easier, so we do, flushing ALL pages. This ensures the actual
+ * audio data will start on a new page
+ */
+ while(!eos){
+ int result=ogg_stream_flush(&os,&og);
+ if(result==0)break;
+ fwrite(og.header,1,og.header_len,stdout);
+ fwrite(og.body,1,og.body_len,stdout);
+ }
+
+ }
+
+ while(!eos){
+ long i;
+ long bytes=fread(readbuffer,1,READ*4,stdin); /* stereo hardwired here */
+
+ if(bytes==0){
+ /* end of file. this can be done implicitly in the mainline,
+ but it's easier to see here in non-clever fashion.
+ Tell the library we're at end of stream so that it can handle
+ the last frame and mark end of stream in the output properly */
+ vorbis_analysis_wrote(&vd,0);
+
+ }else{
+ /* data to encode */
+
+ /* expose the buffer to submit data */
+ float **buffer=vorbis_analysis_buffer(&vd,READ);
+
+ /* uninterleave samples */
+ for(i=0;i<bytes/4;i++){
+ buffer[0][i]=((readbuffer[i*4+1]<<8)|
+ (0x00ff&(int)readbuffer[i*4]))/32768.f;
+ buffer[1][i]=((readbuffer[i*4+3]<<8)|
+ (0x00ff&(int)readbuffer[i*4+2]))/32768.f;
+ }
+
+ /* tell the library how much we actually submitted */
+ vorbis_analysis_wrote(&vd,i);
+ }
+
+ /* vorbis does some data preanalysis, then divvies up blocks for
+ more involved (potentially parallel) processing. Get a single
+ block for encoding now */
+ while(vorbis_analysis_blockout(&vd,&vb)==1){
+
+ /* analysis */
+ vorbis_analysis(&vb,&op);
+
+ /* weld the packet into the bitstream */
+ ogg_stream_packetin(&os,&op);
+
+ /* write out pages (if any) */
+ while(!eos){
+ int result=ogg_stream_pageout(&os,&og);
+ if(result==0)break;
+ fwrite(og.header,1,og.header_len,stdout);
+ fwrite(og.body,1,og.body_len,stdout);
+
+ /* this could be set above, but for illustrative purposes, I do
+ it here (to show that vorbis does know where the stream ends) */
+
+ if(ogg_page_eos(&og))eos=1;
+
+ }
+ }
+ }
+
+ /* clean up and exit. vorbis_info_clear() must be called last */
+
+ ogg_stream_clear(&os);
+ vorbis_block_clear(&vb);
+ vorbis_dsp_clear(&vd);
+ vorbis_info_clear(&vi);
+
+ /* ogg_page and ogg_packet structs always point to storage in
+ libvorbis. They're never freed or manipulated directly */
+
+ fprintf(stderr,"Done.\n");
+ return(0);
+}
+
diff --git a/include/vorbis/codec.h b/include/vorbis/codec.h
new file mode 100644
index 00000000..c3f12658
--- /dev/null
+++ b/include/vorbis/codec.h
@@ -0,0 +1,225 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: libvorbis codec headers
+ last mod: $Id: codec.h,v 1.33.2.1 2000/12/27 23:46:34 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _vorbis_codec_h_
+#define _vorbis_codec_h_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include <ogg/ogg.h>
+
+typedef struct vorbis_info{
+ int version;
+ int channels;
+ long rate;
+
+ /* The below bitrate declarations are *hints*.
+ Combinations of the three values carry the following implications:
+
+ all three set to the same value:
+ implies a fixed rate bitstream
+ only nominal set:
+ implies a VBR stream that averages the nominal bitrate. No hard
+ upper/lower limit
+ upper and or lower set:
+ implies a VBR bitstream that obeys the bitrate limits. nominal
+ may also be set to give a nominal rate.
+ none set:
+ the coder does not care to speculate.
+ */
+
+ long bitrate_upper;
+ long bitrate_nominal;
+ long bitrate_lower;
+ long bitrate_window;
+
+ 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;
+
+ float **pcm;
+ float **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;
+
+ ogg_int64_t glue_bits;
+ ogg_int64_t time_bits;
+ ogg_int64_t floor_bits;
+ ogg_int64_t res_bits;
+
+ void *backend_state;
+} vorbis_dsp_state;
+
+typedef struct vorbis_block{
+ /* necessary stream state for linking to the framing abstraction */
+ float **pcm; /* this is a pointer into local storage */
+ float **pcmdelay; /* 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;
+
+ /* bitmetrics for the frame */
+ long glue_bits;
+ long time_bits;
+ long floor_bits;
+ long res_bits;
+
+} 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;
+ char *vendor;
+
+} vorbis_comment;
+
+
+/* libvorbis encodes in two abstraction layers; first we perform DSP
+ and produce a packet (see docs/analysis.txt). The packet is then
+ coded into a framed OggSquish bitstream by the second layer (see
+ docs/framing.txt). Decode is the reverse process; we sync/frame
+ the bitstream and extract individual packets, then decode the
+ packet back into PCM audio.
+
+ The extra framing/packetizing is used in streaming formats, such as
+ files. Over the net (such as with UDP), the framing and
+ packetization aren't necessary as they're provided by the transport
+ and the streaming layer is not used */
+
+/* Vorbis PRIMITIVES: general ***************************************/
+
+extern void vorbis_info_init(vorbis_info *vi);
+extern void vorbis_info_clear(vorbis_info *vi);
+extern void vorbis_comment_init(vorbis_comment *vc);
+extern void vorbis_comment_add(vorbis_comment *vc, char *comment);
+extern void vorbis_comment_add_tag(vorbis_comment *vc,
+ char *tag, char *contents);
+extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count);
+extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag);
+extern void vorbis_comment_clear(vorbis_comment *vc);
+
+extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
+extern int vorbis_block_clear(vorbis_block *vb);
+extern void vorbis_dsp_clear(vorbis_dsp_state *v);
+
+/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/
+
+extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi);
+extern int vorbis_analysis_headerout(vorbis_dsp_state *v,
+ vorbis_comment *vc,
+ ogg_packet *op,
+ ogg_packet *op_comm,
+ ogg_packet *op_code);
+extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals);
+extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals);
+extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb);
+extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op);
+
+/* Vorbis PRIMITIVES: synthesis layer *******************************/
+extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,
+ ogg_packet *op);
+
+extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi);
+extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op);
+extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb);
+extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm);
+extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples);
+
+/* Vorbis ERRORS and return codes ***********************************/
+
+#define OV_FALSE -1
+#define OV_EOF -2
+#define OV_HOLE -3
+
+#define OV_EREAD -128
+#define OV_EFAULT -129
+#define OV_EIMPL -130
+#define OV_EINVAL -131
+#define OV_ENOTVORBIS -132
+#define OV_EBADHEADER -133
+#define OV_EVERSION -134
+#define OV_ENOTAUDIO -135
+#define OV_EBADPACKET -136
+#define OV_EBADLINK -137
+#define OV_ENOSEEK -138
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/lib/analysis.c b/lib/analysis.c
new file mode 100644
index 00000000..bd6029fe
--- /dev/null
+++ b/lib/analysis.c
@@ -0,0 +1,107 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: single-block PCM analysis mode dispatch
+ last mod: $Id: analysis.c,v 1.40.2.1 2000/12/27 23:46:34 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "registry.h"
+#include "scales.h"
+#include "os.h"
+
+/* decides between modes, dispatches to the appropriate mapping. */
+int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
+ vorbis_dsp_state *vd=vb->vd;
+ backend_lookup_state *b=vd->backend_state;
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ int type,ret;
+ int mode=0;
+
+ vb->glue_bits=0;
+ vb->time_bits=0;
+ vb->floor_bits=0;
+ vb->res_bits=0;
+
+ /* first things first. Make sure encode is ready */
+ oggpack_reset(&vb->opb);
+ /* Encode the packet type */
+ oggpack_write(&vb->opb,0,1);
+
+ /* currently lazy. Short block dispatches to 0, long to 1. */
+
+ if(vb->W &&ci->modes>1)mode=1;
+ type=ci->map_type[ci->mode_param[mode]->mapping];
+ vb->mode=mode;
+
+ /* Encode frame mode, pre,post windowsize, then dispatch */
+ oggpack_write(&vb->opb,mode,b->modebits);
+ if(vb->W){
+ oggpack_write(&vb->opb,vb->lW,1);
+ oggpack_write(&vb->opb,vb->nW,1);
+ fprintf(stderr,"*");
+ }else{
+ fprintf(stderr,".");
+ }
+
+ if((ret=_mapping_P[type]->forward(vb,b->mode[mode])))
+ return(ret);
+
+ /* set up the packet wrapper */
+
+ op->packet=oggpack_get_buffer(&vb->opb);
+ op->bytes=oggpack_bytes(&vb->opb);
+ op->b_o_s=0;
+ op->e_o_s=vb->eofflag;
+ op->granulepos=vb->granulepos;
+ op->packetno=vb->sequence; /* for sake of completeness */
+
+ return(0);
+}
+
+/* there was no great place to put this.... */
+void _analysis_output(char *base,int i,float *v,int n,int bark,int dB){
+#ifdef ANALYSIS
+ int j;
+ FILE *of;
+ char buffer[80];
+ sprintf(buffer,"%s_%d.m",base,i);
+ of=fopen(buffer,"w");
+
+ if(!of)perror("failed to open data dump file");
+
+ for(j=0;j<n;j++){
+ if(dB && v[j]==0)
+ fprintf(of,"\n\n");
+ else{
+ if(bark)
+ fprintf(of,"%g ",toBARK(22050.f*j/n));
+ else
+ fprintf(of,"%g ",(double)j);
+
+ if(dB){
+ fprintf(of,"%g\n",todB(fabs(v[j])));
+ }else{
+ fprintf(of,"%g\n",v[j]);
+ }
+ }
+ }
+ fclose(of);
+#endif
+}
diff --git a/lib/backends.h b/lib/backends.h
new file mode 100644
index 00000000..3c1b7367
--- /dev/null
+++ b/lib/backends.h
@@ -0,0 +1,148 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: libvorbis backend and mapping structures; needed for
+ static mode headers
+ last mod: $Id: backends.h,v 1.3.2.1 2000/12/27 23:46:34 xiphmont Exp $
+
+ ********************************************************************/
+
+/* this is exposed up here because we need it for static modes.
+ Lookups for each backend aren't exposed because there's no reason
+ to do so */
+
+#ifndef _vorbis_backend_h_
+#define _vorbis_backend_h_
+
+#include "codec_internal.h"
+
+/* this would all be simpler/shorter with templates, but.... */
+/* Transform backend generic *************************************/
+
+/* only mdct right now. Flesh it out more if we ever transcend mdct
+ in the transform domain */
+
+/* Time backend generic ******************************************/
+typedef struct{
+ void (*pack) (vorbis_info_time *,oggpack_buffer *);
+ vorbis_info_time *(*unpack)(vorbis_info *,oggpack_buffer *);
+ vorbis_look_time *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
+ vorbis_info_time *);
+ vorbis_info_time *(*copy_info)(vorbis_info_time *);
+
+ void (*free_info) (vorbis_info_time *);
+ void (*free_look) (vorbis_look_time *);
+ int (*forward) (struct vorbis_block *,vorbis_look_time *,
+ float *,float *);
+ int (*inverse) (struct vorbis_block *,vorbis_look_time *,
+ float *,float *);
+} vorbis_func_time;
+
+typedef struct{
+ int dummy;
+} vorbis_info_time0;
+
+/* Floor backend generic *****************************************/
+typedef struct{
+ void (*pack) (vorbis_info_floor *,oggpack_buffer *);
+ vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *);
+ vorbis_look_floor *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
+ vorbis_info_floor *);
+ vorbis_info_floor *(*copy_info)(vorbis_info_floor *);
+ void (*free_info) (vorbis_info_floor *);
+ void (*free_look) (vorbis_look_floor *);
+ int (*forward) (struct vorbis_block *,vorbis_look_floor *,
+ float *,vorbis_bitbuffer *);
+ float(*forward2) (struct vorbis_block *,vorbis_look_floor *,
+ long,float, vorbis_bitbuffer *);
+ int (*inverse) (struct vorbis_block *,vorbis_look_floor *,
+ float *);
+} vorbis_func_floor;
+
+typedef struct{
+ int order;
+ long rate;
+ long barkmap;
+
+ int ampbits;
+ int ampdB;
+
+ int numbooks; /* <= 16 */
+ int books[16];
+} vorbis_info_floor0;
+
+/* Residue backend generic *****************************************/
+typedef struct{
+ void (*pack) (vorbis_info_residue *,oggpack_buffer *);
+ vorbis_info_residue *(*unpack)(vorbis_info *,oggpack_buffer *);
+ vorbis_look_residue *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
+ vorbis_info_residue *);
+ vorbis_info_residue *(*copy_info)(vorbis_info_residue *);
+ void (*free_info) (vorbis_info_residue *);
+ void (*free_look) (vorbis_look_residue *);
+ int (*forward) (struct vorbis_block *,vorbis_look_residue *,
+ float **,int,vorbis_bitbuffer *);
+ int (*inverse) (struct vorbis_block *,vorbis_look_residue *,
+ float **,int);
+} vorbis_func_residue;
+
+typedef struct vorbis_info_residue0{
+/* block-partitioned VQ coded straight residue */
+ long begin;
+ long end;
+
+ /* first stage (lossless partitioning) */
+ int grouping; /* group n vectors per partition */
+ int partitions; /* possible codebooks for a partition */
+ int groupbook; /* huffbook for partitioning */
+ int secondstages[64]; /* expanded out to pointers in lookup */
+ int booklist[256]; /* list of second stage books */
+
+ /* encode-only heuristic settings */
+ float entmax[64]; /* book entropy threshholds*/
+ float ampmax[64]; /* book amp threshholds*/
+ int subgrp[64]; /* book heuristic subgroup size */
+ int blimit[64]; /* subgroup position limits */
+
+} vorbis_info_residue0;
+
+/* Mapping backend generic *****************************************/
+typedef struct{
+ void (*pack) (vorbis_info *,vorbis_info_mapping *,
+ oggpack_buffer *);
+ vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *);
+ vorbis_look_mapping *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
+ vorbis_info_mapping *);
+ vorbis_info_mapping *(*copy_info)(vorbis_info_mapping *);
+ void (*free_info) (vorbis_info_mapping *);
+ void (*free_look) (vorbis_look_mapping *);
+ int (*forward) (struct vorbis_block *vb,vorbis_look_mapping *);
+ int (*inverse) (struct vorbis_block *vb,vorbis_look_mapping *);
+} vorbis_func_mapping;
+
+typedef struct vorbis_info_mapping0{
+ int submaps; /* <= 16 */
+ int chmuxlist[256]; /* up to 256 channels in a Vorbis stream */
+
+ int timesubmap[16]; /* [mux] */
+ int floorsubmap[16]; /* [mux] submap to floors */
+ int residuesubmap[16]; /* [mux] submap to residue */
+ int psysubmap[16]; /* [mux]; encode only */
+} vorbis_info_mapping0;
+
+#endif
+
+
+
+
+
diff --git a/lib/block.c b/lib/block.c
new file mode 100644
index 00000000..da01551b
--- /dev/null
+++ b/lib/block.c
@@ -0,0 +1,780 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: PCM data vector blocking, windowing and dis/reassembly
+ last mod: $Id: block.c,v 1.42.2.1 2000/12/27 23:46:35 xiphmont Exp $
+
+ Handle windowing, overlap-add, etc of the PCM vectors. This is made
+ more amusing by Vorbis' current two allowed block sizes.
+
+ ********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+
+#include "window.h"
+#include "envelope.h"
+#include "mdct.h"
+#include "lpc.h"
+#include "registry.h"
+#include "codebook.h"
+#include "misc.h"
+#include "os.h"
+
+static int ilog2(unsigned int v){
+ int ret=0;
+ while(v>1){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+/* pcm accumulator examples (not exhaustive):
+
+ <-------------- lW ---------------->
+ <--------------- W ---------------->
+: .....|..... _______________ |
+: .''' | '''_--- | |\ |
+:.....''' |_____--- '''......| | \_______|
+:.................|__________________|_______|__|______|
+ |<------ Sl ------>| > Sr < |endW
+ |beginSl |endSl | |endSr
+ |beginW |endlW |beginSr
+
+
+ |< lW >|
+ <--------------- W ---------------->
+ | | .. ______________ |
+ | | ' `/ | ---_ |
+ |___.'___/`. | ---_____|
+ |_______|__|_______|_________________|
+ | >|Sl|< |<------ Sr ----->|endW
+ | | |endSl |beginSr |endSr
+ |beginW | |endlW
+ mult[0] |beginSl mult[n]
+
+ <-------------- lW ----------------->
+ |<--W-->|
+: .............. ___ | |
+: .''' |`/ \ | |
+:.....''' |/`....\|...|
+:.........................|___|___|___|
+ |Sl |Sr |endW
+ | | |endSr
+ | |beginSr
+ | |endSl
+ |beginSl
+ |beginW
+*/
+
+/* block abstraction setup *********************************************/
+
+#ifndef WORD_ALIGN
+#define WORD_ALIGN 8
+#endif
+
+int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
+ memset(vb,0,sizeof(vorbis_block));
+ vb->vd=v;
+ vb->localalloc=0;
+ vb->localstore=NULL;
+ if(v->analysisp)
+ oggpack_writeinit(&vb->opb);
+
+ return(0);
+}
+
+void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
+ bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
+ if(bytes+vb->localtop>vb->localalloc){
+ /* can't just _ogg_realloc... there are outstanding pointers */
+ if(vb->localstore){
+ struct alloc_chain *link=_ogg_malloc(sizeof(struct alloc_chain));
+ vb->totaluse+=vb->localtop;
+ link->next=vb->reap;
+ link->ptr=vb->localstore;
+ vb->reap=link;
+ }
+ /* highly conservative */
+ vb->localalloc=bytes;
+ vb->localstore=_ogg_malloc(vb->localalloc);
+ vb->localtop=0;
+ }
+ {
+ void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
+ vb->localtop+=bytes;
+ return ret;
+ }
+}
+
+/* reap the chain, pull the ripcord */
+void _vorbis_block_ripcord(vorbis_block *vb){
+ /* reap the chain */
+ struct alloc_chain *reap=vb->reap;
+ while(reap){
+ struct alloc_chain *next=reap->next;
+ _ogg_free(reap->ptr);
+ memset(reap,0,sizeof(struct alloc_chain));
+ _ogg_free(reap);
+ reap=next;
+ }
+ /* consolidate storage */
+ if(vb->totaluse){
+ vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
+ vb->localalloc+=vb->totaluse;
+ vb->totaluse=0;
+ }
+
+ /* pull the ripcord */
+ vb->localtop=0;
+ vb->reap=NULL;
+}
+
+int vorbis_block_clear(vorbis_block *vb){
+ if(vb->vd)
+ if(vb->vd->analysisp)
+ oggpack_writeclear(&vb->opb);
+ _vorbis_block_ripcord(vb);
+ if(vb->localstore)_ogg_free(vb->localstore);
+
+ memset(vb,0,sizeof(vorbis_block));
+ return(0);
+}
+
+/* Analysis side code, but directly related to blocking. Thus it's
+ here and not in analysis.c (which is for analysis transforms only).
+ The init is here because some of it is shared */
+
+static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
+ int i;
+ codec_setup_info *ci=vi->codec_setup;
+ backend_lookup_state *b=NULL;
+
+ memset(v,0,sizeof(vorbis_dsp_state));
+ b=v->backend_state=_ogg_calloc(1,sizeof(backend_lookup_state));
+
+ v->vi=vi;
+ b->modebits=ilog2(ci->modes);
+
+ b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
+ b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
+
+ /* MDCT is tranform 0 */
+
+ b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
+ b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
+ mdct_init(b->transform[0][0],ci->blocksizes[0]);
+ mdct_init(b->transform[1][0],ci->blocksizes[1]);
+
+ b->window[0][0][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
+ b->window[0][0][1]=b->window[0][0][0];
+ b->window[0][1][0]=b->window[0][0][0];
+ b->window[0][1][1]=b->window[0][0][0];
+ b->window[1][0][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
+ b->window[1][0][1]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
+ b->window[1][1][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
+ b->window[1][1][1]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
+
+ for(i=0;i<VI_WINDOWB;i++){
+ b->window[0][0][0][i]=
+ _vorbis_window(i,ci->blocksizes[0],ci->blocksizes[0]/2,ci->blocksizes[0]/2);
+ b->window[1][0][0][i]=
+ _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[0]/2,ci->blocksizes[0]/2);
+ b->window[1][0][1][i]=
+ _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[0]/2,ci->blocksizes[1]/2);
+ b->window[1][1][0][i]=
+ _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[1]/2,ci->blocksizes[0]/2);
+ b->window[1][1][1][i]=
+ _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[1]/2,ci->blocksizes[1]/2);
+ }
+
+ if(encp){ /* encode/decode differ here */
+ /* finish the codebooks */
+ b->fullbooks=_ogg_calloc(ci->books,sizeof(codebook));
+ for(i=0;i<ci->books;i++)
+ vorbis_book_init_encode(b->fullbooks+i,ci->book_param[i]);
+ v->analysisp=1;
+ }else{
+ /* finish the codebooks */
+ b->fullbooks=_ogg_calloc(ci->books,sizeof(codebook));
+ for(i=0;i<ci->books;i++)
+ vorbis_book_init_decode(b->fullbooks+i,ci->book_param[i]);
+ }
+
+ /* initialize the storage vectors to a decent size greater than the
+ minimum */
+
+ v->pcm_storage=8192; /* we'll assume later that we have
+ a minimum of twice the blocksize of
+ accumulated samples in analysis */
+ v->pcm=_ogg_malloc(vi->channels*sizeof(float *));
+ v->pcmret=_ogg_malloc(vi->channels*sizeof(float *));
+ {
+ int i;
+ for(i=0;i<vi->channels;i++)
+ v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(float));
+ }
+
+ /* all 1 (large block) or 0 (small block) */
+ /* explicitly set for the sake of clarity */
+ v->lW=0; /* previous window size */
+ v->W=0; /* current window size */
+
+ /* all vector indexes */
+ v->centerW=ci->blocksizes[1]/2;
+
+ v->pcm_current=v->centerW;
+
+ /* initialize all the mapping/backend lookups */
+ b->mode=_ogg_calloc(ci->modes,sizeof(vorbis_look_mapping *));
+ for(i=0;i<ci->modes;i++){
+ int mapnum=ci->mode_param[i]->mapping;
+ int maptype=ci->map_type[mapnum];
+ b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
+ ci->map_param[mapnum]);
+ }
+
+ return(0);
+}
+
+/* arbitrary settings and spec-mandated numbers get filled in here */
+int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
+ backend_lookup_state *b=NULL;
+
+ _vds_shared_init(v,vi,1);
+ b=v->backend_state;
+
+ /* Initialize the envelope state storage */
+ b->ve=_ogg_calloc(1,sizeof(envelope_lookup));
+ _ve_envelope_init(b->ve,vi);
+
+ return(0);
+}
+
+void vorbis_dsp_clear(vorbis_dsp_state *v){
+ int i,j,k;
+ if(v){
+ vorbis_info *vi=v->vi;
+ codec_setup_info *ci=(vi?vi->codec_setup:NULL);
+ backend_lookup_state *b=v->backend_state;
+
+ if(b){
+ if(b->window[0][0][0]){
+ for(i=0;i<VI_WINDOWB;i++)
+ if(b->window[0][0][0][i])_ogg_free(b->window[0][0][0][i]);
+ _ogg_free(b->window[0][0][0]);
+
+ for(j=0;j<2;j++)
+ for(k=0;k<2;k++){
+ for(i=0;i<VI_WINDOWB;i++)
+ if(b->window[1][j][k][i])_ogg_free(b->window[1][j][k][i]);
+ _ogg_free(b->window[1][j][k]);
+ }
+ }
+
+ if(b->ve){
+ _ve_envelope_clear(b->ve);
+ _ogg_free(b->ve);
+ }
+
+ if(b->transform[0]){
+ mdct_clear(b->transform[0][0]);
+ _ogg_free(b->transform[0][0]);
+ _ogg_free(b->transform[0]);
+ }
+ if(b->transform[1]){
+ mdct_clear(b->transform[1][0]);
+ _ogg_free(b->transform[1][0]);
+ _ogg_free(b->transform[1]);
+ }
+
+ }
+
+ if(v->pcm){
+ for(i=0;i<vi->channels;i++)
+ if(v->pcm[i])_ogg_free(v->pcm[i]);
+ _ogg_free(v->pcm);
+ if(v->pcmret)_ogg_free(v->pcmret);
+ }
+
+ /* free mode lookups; these are actually vorbis_look_mapping structs */
+ if(ci){
+ for(i=0;i<ci->modes;i++){
+ int mapnum=ci->mode_param[i]->mapping;
+ int maptype=ci->map_type[mapnum];
+ if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
+ }
+ /* free codebooks */
+ for(i=0;i<ci->books;i++)
+ if(b && b->fullbooks)vorbis_book_clear(b->fullbooks+i);
+ }
+
+ if(b){
+ if(b->mode)_ogg_free(b->mode);
+ if(b->fullbooks)_ogg_free(b->fullbooks);
+
+ /* free header, header1, header2 */
+ if(b->header)_ogg_free(b->header);
+ if(b->header1)_ogg_free(b->header1);
+ if(b->header2)_ogg_free(b->header2);
+ _ogg_free(b);
+ }
+
+ memset(v,0,sizeof(vorbis_dsp_state));
+ }
+}
+
+float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
+ int i;
+ vorbis_info *vi=v->vi;
+ backend_lookup_state *b=v->backend_state;
+
+ /* free header, header1, header2 */
+ if(b->header)_ogg_free(b->header);b->header=NULL;
+ if(b->header1)_ogg_free(b->header1);b->header1=NULL;
+ if(b->header2)_ogg_free(b->header2);b->header2=NULL;
+
+ /* Do we have enough storage space for the requested buffer? If not,
+ expand the PCM (and envelope) storage */
+
+ if(v->pcm_current+vals>=v->pcm_storage){
+ v->pcm_storage=v->pcm_current+vals*2;
+
+ for(i=0;i<vi->channels;i++){
+ v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(float));
+ }
+ }
+
+ for(i=0;i<vi->channels;i++)
+ v->pcmret[i]=v->pcm[i]+v->pcm_current;
+
+ return(v->pcmret);
+}
+
+static void _preextrapolate_helper(vorbis_dsp_state *v){
+ int i;
+ int order=32;
+ float *lpc=alloca(order*sizeof(float));
+ float *work=alloca(v->pcm_current*sizeof(float));
+ long j;
+ v->preextrapolate=1;
+
+ if(v->pcm_current-v->centerW>order*2){ /* safety */
+ for(i=0;i<v->vi->channels;i++){
+
+ /* need to run the extrapolation in reverse! */
+ for(j=0;j<v->pcm_current;j++)
+ work[j]=v->pcm[i][v->pcm_current-j-1];
+
+ /* prime as above */
+ vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
+
+ /* run the predictor filter */
+ vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
+ order,
+ work+v->pcm_current-v->centerW,
+ v->centerW);
+ for(j=0;j<v->pcm_current;j++)
+ v->pcm[i][v->pcm_current-j-1]=work[j];
+ }
+ }
+}
+
+
+/* call with val<=0 to set eof */
+
+int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
+ vorbis_info *vi=v->vi;
+ codec_setup_info *ci=vi->codec_setup;
+
+ if(vals<=0){
+ int order=32;
+ int i;
+ float *lpc=alloca(order*sizeof(float));
+
+ /* if it wasn't done earlier (very short sample) */
+ if(!v->preextrapolate)
+ _preextrapolate_helper(v);
+
+ /* We're encoding the end of the stream. Just make sure we have
+ [at least] a full block of zeroes at the end. */
+ /* actually, we don't want zeroes; that could drop a large
+ amplitude off a cliff, creating spread spectrum noise that will
+ suck to encode. Extrapolate for the sake of cleanliness. */
+
+ vorbis_analysis_buffer(v,ci->blocksizes[1]*2);
+ v->eofflag=v->pcm_current;
+ v->pcm_current+=ci->blocksizes[1]*2;
+
+ for(i=0;i<vi->channels;i++){
+ if(v->eofflag>order*2){
+ /* extrapolate with LPC to fill in */
+ long n;
+
+ /* make a predictor filter */
+ n=v->eofflag;
+ if(n>ci->blocksizes[1])n=ci->blocksizes[1];
+ vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
+
+ /* run the predictor filter */
+ vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
+ v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
+ }else{
+ /* not enough data to extrapolate (unlikely to happen due to
+ guarding the overlap, but bulletproof in case that
+ assumtion goes away). zeroes will do. */
+ memset(v->pcm[i]+v->eofflag,0,
+ (v->pcm_current-v->eofflag)*sizeof(float));
+
+ }
+ }
+ }else{
+
+ if(v->pcm_current+vals>v->pcm_storage)
+ return(OV_EINVAL);
+
+ v->pcm_current+=vals;
+
+ /* we may want to reverse extrapolate the beginning of a stream
+ too... in case we're beginning on a cliff! */
+ /* clumsy, but simple. It only runs once, so simple is good. */
+ if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
+ _preextrapolate_helper(v);
+
+ }
+ return(0);
+}
+
+/* do the deltas, envelope shaping, pre-echo and determine the size of
+ the next block on which to continue analysis */
+int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
+ int i;
+ vorbis_info *vi=v->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ backend_lookup_state *b=v->backend_state;
+ long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
+
+ /* check to see if we're started... */
+ if(!v->preextrapolate)return(0);
+
+ /* check to see if we're done... */
+ if(v->eofflag==-1)return(0);
+
+ /* By our invariant, we have lW, W and centerW set. Search for
+ the next boundary so we can determine nW (the next window size)
+ which lets us compute the shape of the current block's window */
+
+ if(ci->blocksizes[0]<ci->blocksizes[1]){
+ long largebound;
+ long bp;
+
+ if(v->W)
+ /* min boundary; nW large, next small */
+ largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]/4;
+ else
+ /* min boundary; nW large, next small */
+ largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]*3/4;
+
+ bp=_ve_envelope_search(v,largebound);
+ if(bp==-1)return(0); /* not enough data currently to search for a
+ full long block */
+ v->nW=bp;
+
+ }else
+ v->nW=0;
+
+ centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
+
+ {
+ /* center of next block + next block maximum right side. */
+
+ long blockbound=centerNext+ci->blocksizes[v->nW]/2;
+ if(v->pcm_current<blockbound)return(0); /* not enough data yet;
+ although this check is
+ less strict that the
+ _ve_envelope_search,
+ the search is not run
+ if we only use one
+ block size */
+ }
+
+ /* fill in the block. Note that for a short window, lW and nW are *short*
+ regardless of actual settings in the stream */
+
+ _vorbis_block_ripcord(vb);
+ if(v->W){
+ vb->lW=v->lW;
+ vb->W=v->W;
+ vb->nW=v->nW;
+ }else{
+ vb->lW=0;
+ vb->W=v->W;
+ vb->nW=0;
+ }
+ vb->vd=v;
+ vb->sequence=v->sequence;
+ vb->granulepos=v->granulepos;
+ vb->pcmend=ci->blocksizes[v->W];
+
+ /* copy the vectors; this uses the local storage in vb */
+ {
+ vb->pcm=_vorbis_block_alloc(vb,sizeof(float *)*vi->channels);
+ vb->pcmdelay=_vorbis_block_alloc(vb,sizeof(float *)*vi->channels);
+ for(i=0;i<vi->channels;i++){
+ vb->pcmdelay[i]=
+ _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(float));
+ memcpy(vb->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(float));
+ vb->pcm[i]=vb->pcmdelay[i]+beginW;
+
+ /* before we added the delay
+ vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(float));
+ memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(float));
+ */
+
+ }
+ }
+
+ /* handle eof detection: eof==0 means that we've not yet received EOF
+ eof>0 marks the last 'real' sample in pcm[]
+ eof<0 'no more to do'; doesn't get here */
+
+ if(v->eofflag){
+ if(v->centerW>=v->eofflag){
+ v->eofflag=-1;
+ vb->eofflag=1;
+ return(1);
+ }
+ }
+
+ /* advance storage vectors and clean up */
+ {
+ int new_centerNext=ci->blocksizes[1]/2+ci->delaycache;
+ int movementW=centerNext-new_centerNext;
+
+ if(movementW>0){
+
+ _ve_envelope_shift(b->ve,movementW);
+ v->pcm_current-=movementW;
+
+ for(i=0;i<vi->channels;i++)
+ memmove(v->pcm[i],v->pcm[i]+movementW,
+ v->pcm_current*sizeof(float));
+
+
+ v->lW=v->W;
+ v->W=v->nW;
+ v->centerW=new_centerNext;
+
+ v->sequence++;
+
+ if(v->eofflag){
+ v->eofflag-=movementW;
+ /* do not add padding to end of stream! */
+ if(v->centerW>=v->eofflag){
+ v->granulepos+=movementW-(v->centerW-v->eofflag);
+ }else{
+ v->granulepos+=movementW;
+ }
+ }else{
+ v->granulepos+=movementW;
+ }
+ }
+ }
+
+ /* done */
+ return(1);
+}
+
+int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ _vds_shared_init(v,vi,0);
+
+ /* Adjust centerW to allow an easier mechanism for determining output */
+ v->pcm_returned=v->centerW;
+ v->centerW-= ci->blocksizes[v->W]/4+ci->blocksizes[v->lW]/4;
+ v->granulepos=-1;
+ v->sequence=-1;
+
+ return(0);
+}
+
+/* Unlike in analysis, the window is only partially applied for each
+ block. The time domain envelope is not yet handled at the point of
+ calling (as it relies on the previous block). */
+
+int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
+ vorbis_info *vi=v->vi;
+ codec_setup_info *ci=vi->codec_setup;
+
+ /* Shift out any PCM that we returned previously */
+ /* centerW is currently the center of the last block added */
+
+ if(v->centerW>ci->blocksizes[1]/2 &&
+ /* Quick additional hack; to avoid *alot* of shifts, use an
+ oversized buffer. This increases memory usage, but doesn't make
+ much difference wrt L1/L2 cache pressure. */
+ v->pcm_returned>8192){
+
+ /* don't shift too much; we need to have a minimum PCM buffer of
+ 1/2 long block */
+
+ int shiftPCM=v->centerW-ci->blocksizes[1]/2;
+ shiftPCM=(v->pcm_returned<shiftPCM?v->pcm_returned:shiftPCM);
+
+ v->pcm_current-=shiftPCM;
+ v->centerW-=shiftPCM;
+ v->pcm_returned-=shiftPCM;
+
+ if(shiftPCM){
+ int i;
+ for(i=0;i<vi->channels;i++)
+ memmove(v->pcm[i],v->pcm[i]+shiftPCM,
+ v->pcm_current*sizeof(float));
+ }
+ }
+
+ v->lW=v->W;
+ v->W=vb->W;
+ v->nW=-1;
+
+ v->glue_bits+=vb->glue_bits;
+ v->time_bits+=vb->time_bits;
+ v->floor_bits+=vb->floor_bits;
+ v->res_bits+=vb->res_bits;
+
+ if(v->sequence+1 != vb->sequence)v->granulepos=-1; /* out of sequence;
+ lose count */
+
+ v->sequence=vb->sequence;
+
+ {
+ int sizeW=ci->blocksizes[v->W];
+ int centerW=v->centerW+ci->blocksizes[v->lW]/4+sizeW/4;
+ int beginW=centerW-sizeW/2;
+ int endW=beginW+sizeW;
+ int beginSl;
+ int endSl;
+ int i,j;
+
+ /* Do we have enough PCM/mult storage for the block? */
+ if(endW>v->pcm_storage){
+ /* expand the storage */
+ v->pcm_storage=endW+ci->blocksizes[1];
+
+ for(i=0;i<vi->channels;i++)
+ v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(float));
+ }
+
+ /* overlap/add PCM */
+
+ switch(v->W){
+ case 0:
+ beginSl=0;
+ endSl=ci->blocksizes[0]/2;
+ break;
+ case 1:
+ beginSl=ci->blocksizes[1]/4-ci->blocksizes[v->lW]/4;
+ endSl=beginSl+ci->blocksizes[v->lW]/2;
+ break;
+ default:
+ return(-1);
+ }
+
+ for(j=0;j<vi->channels;j++){
+ float *pcm=v->pcm[j]+beginW;
+ float *p=vb->pcm[j];
+
+ /* the overlap/add section */
+ for(i=beginSl;i<endSl;i++)
+ pcm[i]+=p[i];
+ /* the remaining section */
+ for(;i<sizeW;i++)
+ pcm[i]=p[i];
+ }
+
+ /* track the frame number... This is for convenience, but also
+ making sure our last packet doesn't end with added padding. If
+ the last packet is partial, the number of samples we'll have to
+ return will be past the vb->granulepos.
+
+ This is not foolproof! It will be confused if we begin
+ decoding at the last page after a seek or hole. In that case,
+ we don't have a starting point to judge where the last frame
+ is. For this reason, vorbisfile will always try to make sure
+ it reads the last two marked pages in proper sequence */
+
+ if(v->granulepos==-1)
+ if(vb->granulepos==-1){
+ v->granulepos=0;
+ }else{
+ v->granulepos=vb->granulepos;
+ }
+ else{
+ v->granulepos+=(centerW-v->centerW);
+ if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
+
+ if(v->granulepos>vb->granulepos){
+ long extra=v->granulepos-vb->granulepos;
+
+ if(vb->eofflag){
+ /* partial last frame. Strip the extra samples off */
+ centerW-=extra;
+ }else if(vb->sequence == 1){
+ /* partial first frame. Discard extra leading samples */
+ v->pcm_returned+=extra;
+ if(v->pcm_returned>centerW)v->pcm_returned=centerW;
+
+ }
+
+ }/* else{ Shouldn't happen *unless* the bitstream is out of
+ spec. Either way, believe the bitstream } */
+ v->granulepos=vb->granulepos;
+ }
+ }
+
+ /* Update, cleanup */
+
+ v->centerW=centerW;
+ v->pcm_current=endW;
+
+ if(vb->eofflag)v->eofflag=1;
+ }
+
+ return(0);
+}
+
+/* pcm==NULL indicates we just want the pending samples, no more */
+int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
+ vorbis_info *vi=v->vi;
+ if(v->pcm_returned<v->centerW){
+ if(pcm){
+ int i;
+ for(i=0;i<vi->channels;i++)
+ v->pcmret[i]=v->pcm[i]+v->pcm_returned;
+ *pcm=v->pcmret;
+ }
+ return(v->centerW-v->pcm_returned);
+ }
+ return(0);
+}
+
+int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
+ if(bytes && v->pcm_returned+bytes>v->centerW)return(OV_EINVAL);
+ v->pcm_returned+=bytes;
+ return(0);
+}
+
diff --git a/lib/codec_internal.h b/lib/codec_internal.h
new file mode 100644
index 00000000..d80b08ee
--- /dev/null
+++ b/lib/codec_internal.h
@@ -0,0 +1,117 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: libvorbis codec headers
+ last mod: $Id: codec_internal.h,v 1.3.2.1 2000/12/27 23:46:35 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_CODECI_H_
+#define _V_CODECI_H_
+
+#include "envelope.h"
+#include "codebook.h"
+#include "psy.h"
+#include "bitbuffer.h"
+
+typedef void vorbis_look_time;
+typedef void vorbis_look_mapping;
+typedef void vorbis_look_floor;
+typedef void vorbis_look_residue;
+typedef void vorbis_look_transform;
+
+typedef struct backend_lookup_state {
+ /* local lookup storage */
+ envelope_lookup *ve; /* envelope lookup */
+ float **window[2][2][2]; /* block, leadin, leadout, type */
+ vorbis_look_transform **transform[2]; /* block, type */
+ codebook *fullbooks;
+
+ /* backend lookups are tied to the mode, not the backend or naked mapping */
+ int modebits;
+ vorbis_look_mapping **mode;
+
+ /* local storage, only used on the encoding side. This way the
+ application does not need to worry about freeing some packets'
+ memory and not others'; packet storage is always tracked.
+ Cleared next call to a _dsp_ function */
+ unsigned char *header;
+ unsigned char *header1;
+ unsigned char *header2;
+
+} backend_lookup_state;
+
+/* mode ************************************************************/
+typedef struct {
+ int blockflag;
+ int windowtype;
+ int transformtype;
+ int mapping;
+} vorbis_info_mode;
+
+typedef void vorbis_info_time;
+typedef void vorbis_info_floor;
+typedef void vorbis_info_residue;
+typedef void vorbis_info_mapping;
+
+/* vorbis_info contains all the setup information specific to the
+ specific compression/decompression mode in progress (eg,
+ psychoacoustic settings, channel setup, options, codebook
+ etc).
+*********************************************************************/
+
+typedef struct codec_setup_info {
+
+ /* Vorbis supports only short and long blocks, but allows the
+ encoder to choose the sizes */
+
+ long blocksizes[2];
+
+ /* modes are the primary means of supporting on-the-fly different
+ blocksizes, different channel mappings (LR or mid-side),
+ different residue backends, etc. Each mode consists of a
+ blocksize flag and a mapping (along with the mapping setup */
+
+ int modes;
+ int maps;
+ int times;
+ int floors;
+ int residues;
+ int books;
+ int psys; /* encode only */
+
+ vorbis_info_mode *mode_param[64];
+ int map_type[64];
+ vorbis_info_mapping *map_param[64];
+ int time_type[64];
+ vorbis_info_time *time_param[64];
+ int floor_type[64];
+ vorbis_info_floor *floor_param[64];
+ int residue_type[64];
+ vorbis_info_residue *residue_param[64];
+ static_codebook *book_param[256];
+ vorbis_info_psy *psy_param[64]; /* encode only */
+
+ /* for block long/sort tuning; encode only */
+ int envelopesa;
+ float preecho_thresh;
+ float postecho_thresh;
+ float preecho_minenergy;
+
+ /* delay caching... how many samples to keep around prior to our
+ current block to aid in analysis? */
+ int delaycache;
+
+} codec_setup_info;
+
+#endif
diff --git a/lib/envelope.c b/lib/envelope.c
new file mode 100644
index 00000000..5cc18cdc
--- /dev/null
+++ b/lib/envelope.c
@@ -0,0 +1,233 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: PCM data envelope analysis and manipulation
+ last mod: $Id: envelope.c,v 1.28.2.1 2000/12/27 23:46:35 xiphmont Exp $
+
+ Preecho calculation.
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+
+#include "os.h"
+#include "scales.h"
+#include "envelope.h"
+#include "misc.h"
+
+/* We use a Chebyshev bandbass for the preecho trigger bandpass; it's
+ close enough for sample rates 32000-48000 Hz (corner frequencies at
+ 6k/14k assuming sample rate of 44.1kHz) */
+
+/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher
+ Command line: /www/usr/fisher/helpers/mkfilter -Ch \
+ -6.0000000000e+00 -Bp -o 5 -a 1.3605442177e-01 3.1746031746e-01 -l */
+
+#if 0
+static int cheb_bandpass_stages=10;
+static float cheb_bandpass_gain=5.589612458e+01f;
+static float cheb_bandpass_B[]={-1.f,0.f,5.f,0.f,-10.f,0.f,
+ 10.f,0.f,-5.f,0.f,1f};
+static float cheb_bandpass_A[]={
+ -0.1917409386f,
+ 0.0078657069f,
+ -0.7126903444f,
+ 0.0266343467f,
+ -1.4047174730f,
+ 0.0466964232f,
+ -1.9032773429f,
+ 0.0451493360f,
+ -1.4471447397f,
+ 0.0303413711f};
+#endif
+
+static int cheb_highpass_stages=10;
+static float cheb_highpass_gain= 5.291963434e+01f;
+/* z^-stage, z^-stage+1... */
+static float cheb_highpass_B[]={1.f,-10.f,45.f,-120.f,210.f,
+ -252.f,210.f,-120.f,45.f,-10.f,1.f};
+static float cheb_highpass_A[]={
+ -0.1247628029f,
+ 0.1334086523f,
+ -0.3997715614f,
+ 0.3213011089f,
+ -1.1131924119f,
+ 1.7692446626f,
+ -3.6241199038f,
+ 4.1950871291f,
+ -4.2771757867f,
+ 2.3920318913f};
+
+void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ int ch=vi->channels;
+ int window=ci->envelopesa;
+ int i;
+ e->winlength=window;
+ e->minenergy=fromdB(ci->preecho_minenergy);
+ e->iir=_ogg_calloc(ch,sizeof(IIR_state));
+ e->filtered=_ogg_calloc(ch,sizeof(float *));
+ e->ch=ch;
+ e->storage=128;
+ for(i=0;i<ch;i++){
+ IIR_init(e->iir+i,cheb_highpass_stages,cheb_highpass_gain,
+ cheb_highpass_A,cheb_highpass_B);
+ e->filtered[i]=_ogg_calloc(e->storage,sizeof(float));
+ }
+
+ drft_init(&e->drft,window);
+ e->window=_ogg_malloc(e->winlength*sizeof(float));
+ /* We just use a straight sin(x) window for this */
+ for(i=0;i<e->winlength;i++)
+ e->window[i]=sin((i+.5)/e->winlength*M_PI);
+}
+
+void _ve_envelope_clear(envelope_lookup *e){
+ int i;
+ for(i=0;i<e->ch;i++){
+ IIR_clear((e->iir+i));
+ _ogg_free(e->filtered[i]);
+ }
+ drft_clear(&e->drft);
+ _ogg_free(e->window);
+ _ogg_free(e->filtered);
+ _ogg_free(e->iir);
+ memset(e,0,sizeof(envelope_lookup));
+}
+
+/* straight threshhold based until we find something that works better
+ and isn't patented */
+static float _ve_deltai(envelope_lookup *ve,float *pre,float *post){
+ long n=ve->winlength;
+
+ long i;
+
+ /* we want to have a 'minimum bar' for energy, else we're just
+ basing blocks on quantization noise that outweighs the signal
+ itself (for low power signals) */
+
+ float min=ve->minenergy;
+ float A=min*min*n;
+ float B=A;
+
+ /*_analysis_output("A",granulepos,pre,n,0,0);
+ _analysis_output("B",granulepos,post,n,0,0);*/
+
+ for(i=0;i<n;i++){
+ A+=pre[i]*pre[i];
+ B+=post[i]*post[i];
+ }
+
+ A=todB(A);
+ B=todB(B);
+
+ return(B-A);
+}
+
+static float _ve_ampi(envelope_lookup *ve,float *pre){
+ long n=ve->winlength;
+
+ long i;
+
+ /* we want to have a 'minimum bar' for energy, else we're just
+ basing blocks on quantization noise that outweighs the signal
+ itself (for low power signals) */
+
+ float min=ve->minenergy;
+ float A=min*min*n;
+
+ for(i=0;i<n;i++){
+ A+=pre[i]*pre[i];
+ }
+
+ A=todB(A);
+ return(A);
+}
+
+long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){
+ vorbis_info *vi=v->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ envelope_lookup *ve=((backend_lookup_state *)(v->backend_state))->ve;
+ long i,j;
+
+ /* make sure we have enough storage to match the PCM */
+ if(v->pcm_storage>ve->storage){
+ ve->storage=v->pcm_storage;
+ for(i=0;i<ve->ch;i++)
+ ve->filtered[i]=_ogg_realloc(ve->filtered[i],ve->storage*sizeof(float));
+ }
+
+ /* catch up the highpass to match the pcm */
+ for(i=0;i<ve->ch;i++){
+ float *filtered=ve->filtered[i];
+ float *pcm=v->pcm[i];
+ IIR_state *iir=ve->iir+i;
+ int flag=1;
+
+ for(j=ve->current;j<v->pcm_current;j++){
+ filtered[j]=IIR_filter(iir,pcm[j]);
+ if(pcm[j])flag=0;
+ }
+ if(flag && ve->current+64<v->pcm_current)IIR_reset(iir);
+ }
+
+ ve->current=v->pcm_current;
+
+ /* Now search through our cached highpass data for breaking points */
+ /* starting point */
+ if(v->W)
+ j=v->centerW+ci->blocksizes[1]/4-ci->blocksizes[0]/4;
+ else
+ j=v->centerW;
+
+ while(j+ve->winlength<=v->pcm_current){
+ for(i=0;i<ve->ch;i++){
+ float *filtered=ve->filtered[i]+j;
+ float m=_ve_deltai(ve,filtered-ve->winlength,filtered);
+
+ if(m>ci->preecho_thresh){
+ /*granulepos++;*/
+ return(0);
+ }
+ if(m<ci->postecho_thresh){
+ /*granulepos++;*/
+ return(0);
+ }
+ /*granulepos++;*/
+ }
+
+ j+=min(ci->blocksizes[0],ve->winlength)/2;
+
+ if(j>=searchpoint){
+ return(1);
+ }
+ }
+
+ return(-1);
+}
+
+void _ve_envelope_shift(envelope_lookup *e,long shift){
+ int i;
+ for(i=0;i<e->ch;i++)
+ memmove(e->filtered[i],e->filtered[i]+shift,(e->current-shift)*
+ sizeof(float));
+ e->current-=shift;
+}
+
+
diff --git a/lib/floor0.c b/lib/floor0.c
new file mode 100644
index 00000000..76b807da
--- /dev/null
+++ b/lib/floor0.c
@@ -0,0 +1,430 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: floor backend 0 implementation
+ last mod: $Id: floor0.c,v 1.34.2.1 2000/12/27 23:46:35 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "registry.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "codebook.h"
+#include "scales.h"
+#include "misc.h"
+#include "os.h"
+
+#include "misc.h"
+#include <stdio.h>
+
+typedef struct {
+ long n;
+ int ln;
+ int m;
+ int *linearmap;
+
+ vorbis_info_floor0 *vi;
+ lpc_lookup lpclook;
+ float *lsp_look;
+
+} vorbis_look_floor0;
+
+/* infrastructure for finding fit */
+static long _f0_fit(codebook *book,
+ float *orig,
+ float *workfit,
+ int cursor){
+ int dim=book->dim;
+ float norm,base=0.f;
+ int i,best=0;
+ float *lsp=workfit+cursor;
+
+ if(cursor)base=workfit[cursor-1];
+ norm=orig[cursor+dim-1]-base;
+
+ for(i=0;i<dim;i++)
+ lsp[i]=(orig[i+cursor]-base);
+ best=_best(book,lsp,1);
+
+ memcpy(lsp,book->valuelist+best*dim,dim*sizeof(float));
+ for(i=0;i<dim;i++)
+ lsp[i]+=base;
+ return(best);
+}
+
+/***********************************************/
+
+static vorbis_info_floor *floor0_copy_info (vorbis_info_floor *i){
+ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
+ vorbis_info_floor0 *ret=_ogg_malloc(sizeof(vorbis_info_floor0));
+ memcpy(ret,info,sizeof(vorbis_info_floor0));
+ return(ret);
+}
+
+static void floor0_free_info(vorbis_info_floor *i){
+ if(i){
+ memset(i,0,sizeof(vorbis_info_floor0));
+ _ogg_free(i);
+ }
+}
+
+static void floor0_free_look(vorbis_look_floor *i){
+ vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+ if(i){
+ if(look->linearmap)_ogg_free(look->linearmap);
+ if(look->lsp_look)_ogg_free(look->lsp_look);
+ lpc_clear(&look->lpclook);
+ memset(look,0,sizeof(vorbis_look_floor0));
+ _ogg_free(look);
+ }
+}
+
+static void floor0_pack (vorbis_info_floor *i,oggpack_buffer *opb){
+ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
+ int j;
+ oggpack_write(opb,info->order,8);
+ oggpack_write(opb,info->rate,16);
+ oggpack_write(opb,info->barkmap,16);
+ oggpack_write(opb,info->ampbits,6);
+ oggpack_write(opb,info->ampdB,8);
+ oggpack_write(opb,info->numbooks-1,4);
+ for(j=0;j<info->numbooks;j++)
+ oggpack_write(opb,info->books[j],8);
+}
+
+static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
+ codec_setup_info *ci=vi->codec_setup;
+ int j;
+
+ vorbis_info_floor0 *info=_ogg_malloc(sizeof(vorbis_info_floor0));
+ info->order=oggpack_read(opb,8);
+ info->rate=oggpack_read(opb,16);
+ info->barkmap=oggpack_read(opb,16);
+ info->ampbits=oggpack_read(opb,6);
+ info->ampdB=oggpack_read(opb,8);
+ info->numbooks=oggpack_read(opb,4)+1;
+
+ if(info->order<1)goto err_out;
+ if(info->rate<1)goto err_out;
+ if(info->barkmap<1)goto err_out;
+ if(info->numbooks<1)goto err_out;
+
+ for(j=0;j<info->numbooks;j++){
+ info->books[j]=oggpack_read(opb,8);
+ if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
+ }
+ return(info);
+
+ err_out:
+ floor0_free_info(info);
+ return(NULL);
+}
+
+/* initialize Bark scale and normalization lookups. We could do this
+ with static tables, but Vorbis allows a number of possible
+ combinations, so it's best to do it computationally.
+
+ The below is authoritative in terms of defining scale mapping.
+ Note that the scale depends on the sampling rate as well as the
+ linear block and mapping sizes */
+
+static vorbis_look_floor *floor0_look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
+ vorbis_info_floor *i){
+ int j;
+ float scale;
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
+ vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(vorbis_look_floor0));
+ look->m=info->order;
+ look->n=ci->blocksizes[mi->blockflag]/2;
+ look->ln=info->barkmap;
+ look->vi=info;
+
+ if(vd->analysisp)
+ lpc_init(&look->lpclook,look->ln,look->m);
+
+ /* we choose a scaling constant so that:
+ floor(bark(rate/2-1)*C)=mapped-1
+ floor(bark(rate/2)*C)=mapped */
+ scale=look->ln/toBARK(info->rate/2.f);
+
+ /* 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=_ogg_malloc((look->n+1)*sizeof(int));
+ for(j=0;j<look->n;j++){
+ int val=floor( toBARK((info->rate/2.f)/look->n*j)
+ *scale); /* bark numbers represent band edges */
+ if(val>=look->ln)val=look->ln; /* guard against the approximation */
+ look->linearmap[j]=val;
+ }
+ look->linearmap[j]=-1;
+
+ look->lsp_look=_ogg_malloc(look->ln*sizeof(float));
+ for(j=0;j<look->ln;j++)
+ look->lsp_look[j]=2*cos(M_PI/look->ln*j);
+
+ return look;
+}
+
+/* less efficient than the decode side (written for clarity). We're
+ not bottlenecked here anyway */
+
+float _curve_to_lpc(float *curve,float *lpc,
+ vorbis_look_floor0 *l){
+ /* map the input curve to a bark-scale curve for encoding */
+
+ int mapped=l->ln;
+ float *work=alloca(sizeof(float)*mapped);
+ int i,j,last=0;
+ int bark=0;
+
+ memset(work,0,sizeof(float)*mapped);
+
+ /* Only the decode side is behavior-specced; for now in the encoder,
+ we select the maximum value of each band as representative (this
+ helps make sure peaks don't go out of range. In error terms,
+ selecting min would make more sense, but the codebook is trained
+ numerically, so we don't actually lose. We'd still want to
+ use the original curve for error and noise estimation */
+
+ for(i=0;i<l->n;i++){
+ bark=l->linearmap[i];
+ if(work[bark]<curve[i])work[bark]=curve[i];
+ if(bark>last+1){
+ /* If the bark scale is climbing rapidly, some bins may end up
+ going unused. This isn't a waste actually; it keeps the
+ scale resolution even so that the LPC generator has an easy
+ time. However, if we leave the bins empty we lose energy.
+ So, fill 'em in. The decoder does not do anything with he
+ unused bins, so we can fill them anyway we like to end up
+ with a better spectral curve */
+
+ /* we'll always have a bin zero, so we don't need to guard init */
+ long span=bark-last;
+ for(j=1;j<span;j++){
+ float del=(float)j/span;
+ work[j+last]=work[bark]*del+work[last]*(1.f-del);
+ }
+ }
+ last=bark;
+ }
+
+ /* If we're over-ranged to avoid edge effects, fill in the end of spectrum gap */
+ for(i=bark+1;i<mapped;i++)
+ work[i]=work[i-1];
+
+ return vorbis_lpc_from_curve(work,lpc,&(l->lpclook));
+}
+
+/* generate the whole freq response curve of an LSP IIR filter */
+/* didn't need in->out seperation, modifies the flr[] vector; takes in
+ a dB scale floor, puts out linear */
+static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
+ float *flr,vorbis_bitbuffer *vbb){
+ long j;
+ vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+ vorbis_info_floor0 *info=look->vi;
+ float amp;
+ long bits=0;
+ long val=0;
+ static int seq=0;
+
+#ifdef TRAIN_LSP
+ FILE *of;
+ FILE *ef;
+ char buffer[80];
+
+#if 1
+ sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
+ of=fopen(buffer,"a");
+#endif
+
+ sprintf(buffer,"lsp0ent_%d.vqd",vb->mode);
+ ef=fopen(buffer,"a");
+#endif
+
+ /* our floor comes in on a [-Inf...0] dB scale. The curve has to be
+ positive, so we offset it. */
+
+ for(j=0;j<look->n;j++)
+ flr[j]+=info->ampdB;
+
+ /* use 'out' as temp storage */
+ /* Convert our floor to a set of lpc coefficients */
+ amp=sqrt(_curve_to_lpc(flr,flr,look));
+
+ /* amp is in the range (0. to ampdB]. Encode that range using
+ ampbits bits */
+
+ {
+ long maxval=(1L<<info->ampbits)-1;
+
+ val=rint(amp/info->ampdB*maxval);
+
+ if(val<0)val=0; /* likely */
+ if(val>maxval)val=maxval; /* not bloody likely */
+
+ /*oggpack_write(&vb->opb,val,info->ampbits);*/
+ if(val>0)
+ amp=(float)val/maxval*info->ampdB;
+ else
+ amp=0;
+ }
+
+ if(val){
+ float *lspwork=alloca(look->m*sizeof(float));
+
+ /* the spec supports using one of a number of codebooks. Right
+ now, encode using this lib supports only one */
+ backend_lookup_state *be=vb->vd->backend_state;
+ codebook *b=be->fullbooks+info->books[0];
+ bitbuf_write(vbb,0,_ilog(info->numbooks));
+
+ /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
+ vorbis_lpc_to_lsp(flr,flr,look->m);
+
+#ifdef ANALYSIS
+#ifndef TRAIN_LSP
+
+ memcpy(lspwork,flr,look->m*sizeof(float));
+ vorbis_lsp_to_curve(flr,look->linearmap,look->n,look->ln,
+ lspwork,look->m,amp,info->ampdB);
+ _analysis_output("prefit",seq,flr,look->n,0,1);
+
+#endif
+#endif
+
+
+#if 1
+#ifdef TRAIN_LSP
+ {
+ float last=0.f;
+ for(j=0;j<look->m;j++){
+ fprintf(of,"%.12g, ",flr[j]-last);
+ last=flr[j];
+ }
+ }
+ fprintf(of,"\n");
+ fclose(of);
+#endif
+#endif
+
+ /* code the spectral envelope, and keep track of the actual
+ quantized values; we don't want creeping error as each block is
+ nailed to the last quantized value of the previous block. */
+
+ for(j=0;j<look->m;j+=b->dim){
+ int entry=_f0_fit(b,flr,lspwork,j);
+ bits+=vorbis_book_bufencode(b,entry,vbb);
+
+#ifdef TRAIN_LSP
+ fprintf(ef,"%d,\n",entry);
+#endif
+
+ }
+
+#ifdef TRAIN_LSP
+ fclose(ef);
+#endif
+
+ /* take the coefficients back to a spectral envelope curve */
+ vorbis_lsp_to_curve(flr,look->linearmap,look->n,look->ln,
+ lspwork,look->m,amp,info->ampdB);
+ return(val);
+ }
+
+ memset(flr,0,sizeof(float)*look->n);
+ seq++;
+ return(val);
+}
+
+static float floor0_forward2(vorbis_block *vb,vorbis_look_floor *i,
+ long amp,float error,
+ vorbis_bitbuffer *vbb){
+
+ vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+ vorbis_info_floor0 *info=look->vi;
+ if(amp){
+ long maxval=(1L<<info->ampbits)-1;
+ long adj=rint(todB(error)/info->ampdB*maxval/2);
+
+ amp+=adj;
+ if(amp<1)amp=1;
+
+ oggpack_write(&vb->opb,amp,info->ampbits);
+ bitbuf_pack(&vb->opb,vbb);
+ return(fromdB((float)adj/maxval*info->ampdB));
+ }else{
+ oggpack_write(&vb->opb,0,info->ampbits);
+ bitbuf_pack(&vb->opb,vbb);
+ }
+ return(0.f);
+}
+
+
+static int floor0_inverse(vorbis_block *vb,vorbis_look_floor *i,float *out){
+ vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+ vorbis_info_floor0 *info=look->vi;
+ int j,k;
+
+ int ampraw=oggpack_read(&vb->opb,info->ampbits);
+ if(ampraw>0){ /* also handles the -1 out of data case */
+ long maxval=(1<<info->ampbits)-1;
+ float amp=(float)ampraw/maxval*info->ampdB;
+ int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
+ float *lsp=alloca(sizeof(float)*look->m);
+
+ if(booknum!=-1){
+ backend_lookup_state *be=vb->vd->backend_state;
+ codebook *b=be->fullbooks+info->books[booknum];
+ float last=0.f;
+
+ memset(out,0,sizeof(float)*look->m);
+
+ for(j=0;j<look->m;j+=b->dim)
+ if(vorbis_book_decodevs(b,lsp+j,&vb->opb,1,-1)==-1)goto eop;
+ for(j=0;j<look->m;){
+ for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
+ last=lsp[j-1];
+ }
+
+ /* take the coefficients back to a spectral envelope curve */
+ vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
+ lsp,look->m,amp,info->ampdB);
+ return(1);
+ }
+ }
+
+ eop:
+ memset(out,0,sizeof(float)*look->n);
+ return(0);
+}
+
+/* export hooks */
+vorbis_func_floor floor0_exportbundle={
+ &floor0_pack,&floor0_unpack,&floor0_look,&floor0_copy_info,&floor0_free_info,
+ &floor0_free_look,&floor0_forward,&floor0_forward2,&floor0_inverse
+};
+
+
diff --git a/lib/info.c b/lib/info.c
new file mode 100644
index 00000000..54558689
--- /dev/null
+++ b/lib/info.c
@@ -0,0 +1,571 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: maintain the info structure, info <-> header packets
+ last mod: $Id: info.c,v 1.33.2.1 2000/12/27 23:46:35 xiphmont Exp $
+
+ ********************************************************************/
+
+/* general handling of the header and the vorbis_info structure (and
+ substructures) */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "backends.h"
+#include "codec_internal.h"
+#include "codebook.h"
+#include "registry.h"
+#include "window.h"
+#include "psy.h"
+#include "misc.h"
+#include "os.h"
+
+/* helpers */
+static int ilog2(unsigned int v){
+ int ret=0;
+ while(v>1){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+static void _v_writestring(oggpack_buffer *o,char *s){
+ while(*s){
+ oggpack_write(o,*s++,8);
+ }
+}
+
+static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
+ while(bytes--){
+ *buf++=oggpack_read(o,8);
+ }
+}
+
+void vorbis_comment_init(vorbis_comment *vc){
+ memset(vc,0,sizeof(vorbis_comment));
+}
+
+void vorbis_comment_add(vorbis_comment *vc,char *comment){
+ vc->user_comments=_ogg_realloc(vc->user_comments,
+ (vc->comments+2)*sizeof(char *));
+ vc->comment_lengths=_ogg_realloc(vc->comment_lengths,
+ (vc->comments+2)*sizeof(int));
+ vc->user_comments[vc->comments]=strdup(comment);
+ vc->comment_lengths[vc->comments]=strlen(comment);
+ vc->comments++;
+ vc->user_comments[vc->comments]=NULL;
+}
+
+void vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){
+ char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
+ strcpy(comment, tag);
+ strcat(comment, "=");
+ strcat(comment, contents);
+ vorbis_comment_add(vc, comment);
+}
+
+/* This is more or less the same as strncasecmp - but that doesn't exist
+ * everywhere, and this is a fairly trivial function, so we include it */
+static int tagcompare(const char *s1, const char *s2, int n){
+ int c=0;
+ while(c < n){
+ if(toupper(s1[c]) != toupper(s2[c]))
+ return !0;
+ c++;
+ }
+ return 0;
+}
+
+char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){
+ long i;
+ int found = 0;
+ int taglen = strlen(tag)+1; /* +1 for the = we append */
+ char *fulltag = alloca(taglen+ 1);
+
+ strcpy(fulltag, tag);
+ strcat(fulltag, "=");
+
+ for(i=0;i<vc->comments;i++){
+ if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
+ if(count == found)
+ /* We return a pointer to the data, not a copy */
+ return vc->user_comments[i] + taglen;
+ else
+ found++;
+ }
+ }
+ return NULL; /* didn't find anything */
+}
+
+int vorbis_comment_query_count(vorbis_comment *vc, char *tag){
+ int i,count=0;
+ int taglen = strlen(tag)+1; /* +1 for the = we append */
+ char *fulltag = alloca(taglen+1);
+ strcpy(fulltag,tag);
+ strcat(fulltag, "=");
+
+ for(i=0;i<vc->comments;i++){
+ if(!tagcompare(vc->user_comments[i], fulltag, taglen))
+ count++;
+ }
+
+ return count;
+}
+
+void vorbis_comment_clear(vorbis_comment *vc){
+ if(vc){
+ long i;
+ for(i=0;i<vc->comments;i++)
+ if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
+ if(vc->user_comments)_ogg_free(vc->user_comments);
+ if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
+ if(vc->vendor)_ogg_free(vc->vendor);
+ }
+ memset(vc,0,sizeof(vorbis_comment));
+}
+
+/* used by synthesis, which has a full, alloced vi */
+void vorbis_info_init(vorbis_info *vi){
+ memset(vi,0,sizeof(vorbis_info));
+ vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info));
+}
+
+void vorbis_info_clear(vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ int i;
+
+ if(ci){
+
+ for(i=0;i<ci->modes;i++)
+ if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
+
+ for(i=0;i<ci->maps;i++) /* unpack does the range checking */
+ _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
+
+ for(i=0;i<ci->times;i++) /* unpack does the range checking */
+ _time_P[ci->time_type[i]]->free_info(ci->time_param[i]);
+
+ for(i=0;i<ci->floors;i++) /* unpack does the range checking */
+ _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
+
+ for(i=0;i<ci->residues;i++) /* unpack does the range checking */
+ _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
+
+ for(i=0;i<ci->books;i++){
+ if(ci->book_param[i]){
+ /* knows if the book was not alloced */
+ vorbis_staticbook_destroy(ci->book_param[i]);
+ }
+ }
+
+ for(i=0;i<ci->psys;i++)
+ _vi_psy_free(ci->psy_param[i]);
+
+ _ogg_free(ci);
+ }
+
+ memset(vi,0,sizeof(vorbis_info));
+}
+
+/* Header packing/unpacking ********************************************/
+
+static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
+ codec_setup_info *ci=vi->codec_setup;
+ if(!ci)return(OV_EFAULT);
+
+ vi->version=oggpack_read(opb,32);
+ if(vi->version!=0)return(OV_EVERSION);
+
+ vi->channels=oggpack_read(opb,8);
+ vi->rate=oggpack_read(opb,32);
+
+ vi->bitrate_upper=oggpack_read(opb,32);
+ vi->bitrate_nominal=oggpack_read(opb,32);
+ vi->bitrate_lower=oggpack_read(opb,32);
+
+ ci->blocksizes[0]=1<<oggpack_read(opb,4);
+ ci->blocksizes[1]=1<<oggpack_read(opb,4);
+
+ if(vi->rate<1)goto err_out;
+ if(vi->channels<1)goto err_out;
+ if(ci->blocksizes[0]<8)goto err_out;
+ if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
+
+ if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+
+ return(0);
+ err_out:
+ vorbis_info_clear(vi);
+ return(OV_EBADHEADER);
+}
+
+static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
+ int i;
+ int vendorlen=oggpack_read(opb,32);
+ if(vendorlen<0)goto err_out;
+ vc->vendor=_ogg_calloc(vendorlen+1,1);
+ _v_readstring(opb,vc->vendor,vendorlen);
+ vc->comments=oggpack_read(opb,32);
+ if(vc->comments<0)goto err_out;
+ vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(char **));
+ vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(int));
+
+ for(i=0;i<vc->comments;i++){
+ int len=oggpack_read(opb,32);
+ if(len<0)goto err_out;
+ vc->comment_lengths[i]=len;
+ vc->user_comments[i]=_ogg_calloc(len+1,1);
+ _v_readstring(opb,vc->user_comments[i],len);
+ }
+ if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+
+ return(0);
+ err_out:
+ vorbis_comment_clear(vc);
+ return(OV_EBADHEADER);
+}
+
+/* all of the real encoding details are here. The modes, books,
+ everything */
+static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
+ codec_setup_info *ci=vi->codec_setup;
+ int i;
+ if(!ci)return(OV_EFAULT);
+
+ /* codebooks */
+ ci->books=oggpack_read(opb,8)+1;
+ /*ci->book_param=_ogg_calloc(ci->books,sizeof(static_codebook *));*/
+ for(i=0;i<ci->books;i++){
+ ci->book_param[i]=_ogg_calloc(1,sizeof(static_codebook));
+ if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out;
+ }
+
+ /* time backend settings */
+ ci->times=oggpack_read(opb,6)+1;
+ /*ci->time_type=_ogg_malloc(ci->times*sizeof(int));*/
+ /*ci->time_param=_ogg_calloc(ci->times,sizeof(void *));*/
+ for(i=0;i<ci->times;i++){
+ ci->time_type[i]=oggpack_read(opb,16);
+ if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out;
+ ci->time_param[i]=_time_P[ci->time_type[i]]->unpack(vi,opb);
+ if(!ci->time_param[i])goto err_out;
+ }
+
+ /* floor backend settings */
+ ci->floors=oggpack_read(opb,6)+1;
+ /*ci->floor_type=_ogg_malloc(ci->floors*sizeof(int));*/
+ /*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/
+ for(i=0;i<ci->floors;i++){
+ ci->floor_type[i]=oggpack_read(opb,16);
+ if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
+ ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
+ if(!ci->floor_param[i])goto err_out;
+ }
+
+ /* residue backend settings */
+ ci->residues=oggpack_read(opb,6)+1;
+ /*ci->residue_type=_ogg_malloc(ci->residues*sizeof(int));*/
+ /*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/
+ for(i=0;i<ci->residues;i++){
+ ci->residue_type[i]=oggpack_read(opb,16);
+ if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
+ ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
+ if(!ci->residue_param[i])goto err_out;
+ }
+
+ /* map backend settings */
+ ci->maps=oggpack_read(opb,6)+1;
+ /*ci->map_type=_ogg_malloc(ci->maps*sizeof(int));*/
+ /*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/
+ for(i=0;i<ci->maps;i++){
+ ci->map_type[i]=oggpack_read(opb,16);
+ if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
+ ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
+ if(!ci->map_param[i])goto err_out;
+ }
+
+ /* mode settings */
+ ci->modes=oggpack_read(opb,6)+1;
+ /*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/
+ for(i=0;i<ci->modes;i++){
+ ci->mode_param[i]=_ogg_calloc(1,sizeof(vorbis_info_mode));
+ ci->mode_param[i]->blockflag=oggpack_read(opb,1);
+ ci->mode_param[i]->windowtype=oggpack_read(opb,16);
+ ci->mode_param[i]->transformtype=oggpack_read(opb,16);
+ ci->mode_param[i]->mapping=oggpack_read(opb,8);
+
+ if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
+ if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
+ if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
+ }
+
+ if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
+
+ return(0);
+ err_out:
+ vorbis_info_clear(vi);
+ return(OV_EBADHEADER);
+}
+
+/* The Vorbis header is in three packets; the initial small packet in
+ the first page that identifies basic parameters, a second packet
+ with bitstream comments and a third packet that holds the
+ codebook. */
+
+int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
+ oggpack_buffer opb;
+
+ if(op){
+ oggpack_readinit(&opb,op->packet,op->bytes);
+
+ /* Which of the three types of header is this? */
+ /* Also verify header-ness, vorbis */
+ {
+ char buffer[6];
+ int packtype=oggpack_read(&opb,8);
+ memset(buffer,0,6);
+ _v_readstring(&opb,buffer,6);
+ if(memcmp(buffer,"vorbis",6)){
+ /* not a vorbis header */
+ return(OV_ENOTVORBIS);
+ }
+ switch(packtype){
+ case 0x01: /* least significant *bit* is read first */
+ if(!op->b_o_s){
+ /* Not the initial packet */
+ return(OV_EBADHEADER);
+ }
+ if(vi->rate!=0){
+ /* previously initialized info header */
+ return(OV_EBADHEADER);
+ }
+
+ return(_vorbis_unpack_info(vi,&opb));
+
+ case 0x03: /* least significant *bit* is read first */
+ if(vi->rate==0){
+ /* um... we didn't get the initial header */
+ return(OV_EBADHEADER);
+ }
+
+ return(_vorbis_unpack_comment(vc,&opb));
+
+ case 0x05: /* least significant *bit* is read first */
+ if(vi->rate==0 || vc->vendor==NULL){
+ /* um... we didn;t get the initial header or comments yet */
+ return(OV_EBADHEADER);
+ }
+
+ return(_vorbis_unpack_books(vi,&opb));
+
+ default:
+ /* Not a valid vorbis header type */
+ return(OV_EBADHEADER);
+ break;
+ }
+ }
+ }
+ return(OV_EBADHEADER);
+}
+
+/* pack side **********************************************************/
+
+static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ if(!ci)return(OV_EFAULT);
+
+ /* preamble */
+ oggpack_write(opb,0x01,8);
+ _v_writestring(opb,"vorbis");
+
+ /* basic information about the stream */
+ oggpack_write(opb,0x00,32);
+ oggpack_write(opb,vi->channels,8);
+ oggpack_write(opb,vi->rate,32);
+
+ oggpack_write(opb,vi->bitrate_upper,32);
+ oggpack_write(opb,vi->bitrate_nominal,32);
+ oggpack_write(opb,vi->bitrate_lower,32);
+
+ oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
+ oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
+ oggpack_write(opb,1,1);
+
+ return(0);
+}
+
+static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
+ char temp[]="Xiphophorus libVorbis I 20001223";
+
+ /* preamble */
+ oggpack_write(opb,0x03,8);
+ _v_writestring(opb,"vorbis");
+
+ /* vendor */
+ oggpack_write(opb,strlen(temp),32);
+ _v_writestring(opb,temp);
+
+ /* comments */
+
+ oggpack_write(opb,vc->comments,32);
+ if(vc->comments){
+ int i;
+ for(i=0;i<vc->comments;i++){
+ if(vc->user_comments[i]){
+ oggpack_write(opb,vc->comment_lengths[i],32);
+ _v_writestring(opb,vc->user_comments[i]);
+ }else{
+ oggpack_write(opb,0,32);
+ }
+ }
+ }
+ oggpack_write(opb,1,1);
+
+ return(0);
+}
+
+static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
+ codec_setup_info *ci=vi->codec_setup;
+ int i;
+ if(!ci)return(OV_EFAULT);
+
+ oggpack_write(opb,0x05,8);
+ _v_writestring(opb,"vorbis");
+
+ /* books */
+ oggpack_write(opb,ci->books-1,8);
+ for(i=0;i<ci->books;i++)
+ if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out;
+
+ /* times */
+ oggpack_write(opb,ci->times-1,6);
+ for(i=0;i<ci->times;i++){
+ oggpack_write(opb,ci->time_type[i],16);
+ _time_P[ci->time_type[i]]->pack(ci->time_param[i],opb);
+ }
+
+ /* floors */
+ oggpack_write(opb,ci->floors-1,6);
+ for(i=0;i<ci->floors;i++){
+ oggpack_write(opb,ci->floor_type[i],16);
+ _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb);
+ }
+
+ /* residues */
+ oggpack_write(opb,ci->residues-1,6);
+ for(i=0;i<ci->residues;i++){
+ oggpack_write(opb,ci->residue_type[i],16);
+ _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb);
+ }
+
+ /* maps */
+ oggpack_write(opb,ci->maps-1,6);
+ for(i=0;i<ci->maps;i++){
+ oggpack_write(opb,ci->map_type[i],16);
+ _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb);
+ }
+
+ /* modes */
+ oggpack_write(opb,ci->modes-1,6);
+ for(i=0;i<ci->modes;i++){
+ oggpack_write(opb,ci->mode_param[i]->blockflag,1);
+ oggpack_write(opb,ci->mode_param[i]->windowtype,16);
+ oggpack_write(opb,ci->mode_param[i]->transformtype,16);
+ oggpack_write(opb,ci->mode_param[i]->mapping,8);
+ }
+ oggpack_write(opb,1,1);
+
+ return(0);
+err_out:
+ return(-1);
+}
+
+int vorbis_analysis_headerout(vorbis_dsp_state *v,
+ vorbis_comment *vc,
+ ogg_packet *op,
+ ogg_packet *op_comm,
+ ogg_packet *op_code){
+ int ret=OV_EIMPL;
+ vorbis_info *vi=v->vi;
+ oggpack_buffer opb;
+ backend_lookup_state *b=v->backend_state;
+
+ if(!b){
+ ret=OV_EFAULT;
+ goto err_out;
+ }
+
+ /* first header packet **********************************************/
+
+ oggpack_writeinit(&opb);
+ if(_vorbis_pack_info(&opb,vi))goto err_out;
+
+ /* build the packet */
+ if(b->header)_ogg_free(b->header);
+ b->header=_ogg_malloc(oggpack_bytes(&opb));
+ memcpy(b->header,opb.buffer,oggpack_bytes(&opb));
+ op->packet=b->header;
+ op->bytes=oggpack_bytes(&opb);
+ op->b_o_s=1;
+ op->e_o_s=0;
+ op->granulepos=0;
+
+ /* second header packet (comments) **********************************/
+
+ oggpack_reset(&opb);
+ if(_vorbis_pack_comment(&opb,vc))goto err_out;
+
+ if(b->header1)_ogg_free(b->header1);
+ b->header1=_ogg_malloc(oggpack_bytes(&opb));
+ memcpy(b->header1,opb.buffer,oggpack_bytes(&opb));
+ op_comm->packet=b->header1;
+ op_comm->bytes=oggpack_bytes(&opb);
+ op_comm->b_o_s=0;
+ op_comm->e_o_s=0;
+ op_comm->granulepos=0;
+
+ /* third header packet (modes/codebooks) ****************************/
+
+ oggpack_reset(&opb);
+ if(_vorbis_pack_books(&opb,vi))goto err_out;
+
+ if(b->header2)_ogg_free(b->header2);
+ b->header2=_ogg_malloc(oggpack_bytes(&opb));
+ memcpy(b->header2,opb.buffer,oggpack_bytes(&opb));
+ op_code->packet=b->header2;
+ op_code->bytes=oggpack_bytes(&opb);
+ op_code->b_o_s=0;
+ op_code->e_o_s=0;
+ op_code->granulepos=0;
+
+ oggpack_writeclear(&opb);
+ return(0);
+ err_out:
+ oggpack_writeclear(&opb);
+ memset(op,0,sizeof(ogg_packet));
+ memset(op_comm,0,sizeof(ogg_packet));
+ memset(op_code,0,sizeof(ogg_packet));
+
+ if(b->header)_ogg_free(b->header);
+ if(b->header1)_ogg_free(b->header1);
+ if(b->header2)_ogg_free(b->header2);
+ b->header=NULL;
+ b->header1=NULL;
+ b->header2=NULL;
+ return(ret);
+}
+
diff --git a/lib/mapping0.c b/lib/mapping0.c
new file mode 100644
index 00000000..76c97eb1
--- /dev/null
+++ b/lib/mapping0.c
@@ -0,0 +1,441 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: channel mapping 0 implementation
+ last mod: $Id: mapping0.c,v 1.22.2.1 2000/12/27 23:46:35 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "codebook.h"
+#include "bitbuffer.h"
+#include "registry.h"
+#include "psy.h"
+#include "misc.h"
+
+/* simplistic, wasteful way of doing this (unique lookup for each
+ mode/submapping); there should be a central repository for
+ identical lookups. That will require minor work, so I'm putting it
+ off as low priority.
+
+ Why a lookup for each backend in a given mode? Because the
+ blocksize is set by the mode, and low backend lookups may require
+ parameters from other areas of the mode/mapping */
+
+typedef struct {
+ drft_lookup fft_look;
+ vorbis_info_mode *mode;
+ vorbis_info_mapping0 *map;
+
+ vorbis_look_time **time_look;
+ vorbis_look_floor **floor_look;
+
+ vorbis_look_residue **residue_look;
+ vorbis_look_psy *psy_look;
+
+ vorbis_func_time **time_func;
+ vorbis_func_floor **floor_func;
+ vorbis_func_residue **residue_func;
+
+ int ch;
+ long lastframe; /* if a different mode is called, we need to
+ invalidate decay */
+} vorbis_look_mapping0;
+
+static vorbis_info_mapping *mapping0_copy_info(vorbis_info_mapping *vm){
+ vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
+ vorbis_info_mapping0 *ret=_ogg_malloc(sizeof(vorbis_info_mapping0));
+ memcpy(ret,info,sizeof(vorbis_info_mapping0));
+ return(ret);
+}
+
+static void mapping0_free_info(vorbis_info_mapping *i){
+ if(i){
+ memset(i,0,sizeof(vorbis_info_mapping0));
+ _ogg_free(i);
+ }
+}
+
+static void mapping0_free_look(vorbis_look_mapping *look){
+ int i;
+ vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look;
+ if(l){
+ drft_clear(&l->fft_look);
+
+ for(i=0;i<l->map->submaps;i++){
+ l->time_func[i]->free_look(l->time_look[i]);
+ l->floor_func[i]->free_look(l->floor_look[i]);
+ l->residue_func[i]->free_look(l->residue_look[i]);
+ if(l->psy_look)_vp_psy_clear(l->psy_look+i);
+ }
+
+ _ogg_free(l->time_func);
+ _ogg_free(l->floor_func);
+ _ogg_free(l->residue_func);
+ _ogg_free(l->time_look);
+ _ogg_free(l->floor_look);
+ _ogg_free(l->residue_look);
+ if(l->psy_look)_ogg_free(l->psy_look);
+ memset(l,0,sizeof(vorbis_look_mapping0));
+ _ogg_free(l);
+ }
+}
+
+static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
+ vorbis_info_mapping *m){
+ int i;
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_look_mapping0 *look=_ogg_calloc(1,sizeof(vorbis_look_mapping0));
+ vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m;
+ look->mode=vm;
+
+ look->time_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_time *));
+ look->floor_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_floor *));
+
+ look->residue_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_residue *));
+ if(ci->psys)look->psy_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_psy));
+
+ look->time_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_time *));
+ look->floor_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_floor *));
+ look->residue_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_residue *));
+
+ for(i=0;i<info->submaps;i++){
+ int timenum=info->timesubmap[i];
+ int floornum=info->floorsubmap[i];
+ int resnum=info->residuesubmap[i];
+
+ look->time_func[i]=_time_P[ci->time_type[timenum]];
+ look->time_look[i]=look->time_func[i]->
+ look(vd,vm,ci->time_param[timenum]);
+ look->floor_func[i]=_floor_P[ci->floor_type[floornum]];
+ look->floor_look[i]=look->floor_func[i]->
+ look(vd,vm,ci->floor_param[floornum]);
+ look->residue_func[i]=_residue_P[ci->residue_type[resnum]];
+ look->residue_look[i]=look->residue_func[i]->
+ look(vd,vm,ci->residue_param[resnum]);
+
+ if(ci->psys && vd->analysisp){
+ int psynum=info->psysubmap[i];
+ _vp_psy_init(look->psy_look+i,ci->psy_param[psynum],
+ ci->blocksizes[vm->blockflag]/2,vi->rate);
+ }
+ }
+
+ look->ch=vi->channels;
+
+ if(vd->analysisp)drft_init(&look->fft_look,ci->blocksizes[vm->blockflag]);
+ return(look);
+}
+
+static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,oggpack_buffer *opb){
+ int i;
+ vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
+
+ oggpack_write(opb,info->submaps-1,4);
+ /* we don't write the channel submappings if we only have one... */
+ if(info->submaps>1){
+ for(i=0;i<vi->channels;i++)
+ oggpack_write(opb,info->chmuxlist[i],4);
+ }
+ for(i=0;i<info->submaps;i++){
+ oggpack_write(opb,info->timesubmap[i],8);
+ oggpack_write(opb,info->floorsubmap[i],8);
+ oggpack_write(opb,info->residuesubmap[i],8);
+ }
+}
+
+/* also responsible for range checking */
+static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
+ int i;
+ vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(vorbis_info_mapping0));
+ codec_setup_info *ci=vi->codec_setup;
+ memset(info,0,sizeof(vorbis_info_mapping0));
+
+ info->submaps=oggpack_read(opb,4)+1;
+
+ if(info->submaps>1){
+ for(i=0;i<vi->channels;i++){
+ info->chmuxlist[i]=oggpack_read(opb,4);
+ if(info->chmuxlist[i]>=info->submaps)goto err_out;
+ }
+ }
+ for(i=0;i<info->submaps;i++){
+ info->timesubmap[i]=oggpack_read(opb,8);
+ if(info->timesubmap[i]>=ci->times)goto err_out;
+ info->floorsubmap[i]=oggpack_read(opb,8);
+ if(info->floorsubmap[i]>=ci->floors)goto err_out;
+ info->residuesubmap[i]=oggpack_read(opb,8);
+ if(info->residuesubmap[i]>=ci->residues)goto err_out;
+ }
+
+ return info;
+
+ err_out:
+ mapping0_free_info(info);
+ return(NULL);
+}
+
+#include "os.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "envelope.h"
+#include "mdct.h"
+#include "psy.h"
+#include "scales.h"
+
+/* no time mapping implementation for now */
+static long seq=0;
+static int mapping0_forward(vorbis_block *vb,vorbis_look_mapping *l){
+ vorbis_dsp_state *vd=vb->vd;
+ vorbis_info *vi=vd->vi;
+ backend_lookup_state *b=vb->vd->backend_state;
+ vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
+ vorbis_info_mapping0 *info=look->map;
+ vorbis_info_mode *mode=look->mode;
+ int n=vb->pcmend;
+ int i,j;
+ float *window=b->window[vb->W][vb->lW][vb->nW][mode->windowtype];
+
+ float **pcmbundle=alloca(sizeof(float *)*vi->channels);
+
+ int *nonzero=alloca(sizeof(int)*vi->channels);
+
+ float **floor=_vorbis_block_alloc(vb,vi->channels*sizeof(float *));
+ float *additional=_vorbis_block_alloc(vb,n*sizeof(float));
+
+ vorbis_bitbuffer vbb_res;
+ vorbis_bitbuffer *vbb_flr=_vorbis_block_alloc(vb,
+ sizeof(vorbis_bitbuffer)*
+ vi->channels);
+
+ for(i=0;i<vi->channels;i++)
+ bitbuf_init(vbb_flr+i,vb);
+ bitbuf_init(&vbb_res,vb);
+
+ for(i=0;i<vi->channels;i++){
+ float *pcm=vb->pcm[i];
+ float scale=4.f/n;
+ int submap=info->chmuxlist[i];
+
+ /* window the PCM data */
+ for(j=0;j<n;j++)
+ additional[j]=pcm[j]*=window[j];
+
+ /* transform the PCM data */
+ /* only MDCT right now.... */
+ mdct_forward(b->transform[vb->W][0],pcm,pcm);
+
+ /* FFT yields more accurate tonal estimation (not phase sensitive) */
+ drft_forward(&look->fft_look,additional);
+
+ additional[0]*=scale;
+ for(j=1;j<n-1;j+=2)
+ additional[(j+1)>>1]=scale*FAST_HYPOT(additional[j],additional[j+1]);
+
+ /* set up our masking data working vector, and stash unquantized
+ data for later */
+ memcpy(pcm+n/2,pcm,n*sizeof(float)/2);
+ memcpy(additional+n/2,pcm,n*sizeof(float)/2);
+
+ /* begin masking work */
+ floor[i]=_vorbis_block_alloc(vb,n*sizeof(float)/2);
+
+ _analysis_output("fft",seq,additional,n/2,0,1);
+ _analysis_output("mdct",seq,additional+n/2,n/2,0,1);
+ _analysis_output("lfft",seq,additional,n/2,0,0);
+ _analysis_output("lmdct",seq,additional+n/2,n/2,0,0);
+
+ /* perform psychoacoustics; do masking */
+ _vp_compute_mask(look->psy_look+submap,additional,additional+n/2,
+ floor[i],NULL);
+
+ _analysis_output("prefloor",seq,floor[i],n/2,0,0);
+
+ /* perform floor encoding */
+ nonzero[i]=look->floor_func[submap]->
+ forward(vb,look->floor_look[submap],floor[i],vbb_flr+i);
+
+ _analysis_output("floor",seq,floor[i],n/2,0,1);
+
+ /* apply the floor, do optional noise levelling */
+ _vp_apply_floor(look->psy_look+submap,pcm,floor[i]);
+
+ _analysis_output("res",seq++,pcm,n/2,0,0);
+
+#ifdef TRAIN_RES
+ if(nonzero[i]){
+ FILE *of;
+ char buffer[80];
+ int i;
+
+ sprintf(buffer,"residue_%d.vqd",vb->mode);
+ of=fopen(buffer,"a");
+ for(i=0;i<n/2;i++)
+ fprintf(of,"%.2f, ",pcm[i]);
+ fprintf(of,"\n");
+ fclose(of);
+ }
+#endif
+
+ }
+
+ /* perform residue encoding with residue mapping; this is
+ multiplexed. All the channels belonging to one submap are
+ encoded (values interleaved), then the next submap, etc */
+
+ for(i=0;i<info->submaps;i++){
+ int ch_in_bundle=0;
+ for(j=0;j<vi->channels;j++){
+ if(info->chmuxlist[j]==i && nonzero[j]>0){
+ pcmbundle[ch_in_bundle++]=vb->pcm[j];
+ }
+ }
+
+ look->residue_func[i]->forward(vb,look->residue_look[i],
+ pcmbundle,ch_in_bundle,&vbb_res);
+ }
+
+ /* go back and compute the original MDCT inverse and our quantized
+ inverse; we'll want to give the floor mapping a shot at
+ massaging things before we write out the final version. */
+
+ {
+ for(i=0;i<vi->channels;i++){
+ float *pcm=vb->pcm[i];
+ float *pcmori=vb->pcm[i]+n/2;
+ float *quant=floor[i];
+ float num=0.f,den=0.f;
+ int submap=info->chmuxlist[i];
+
+ if(nonzero[i]){
+
+ mdct_backward(b->transform[vb->W][0],pcm+n/2,additional);
+ for(j=0;j<n;j++)
+ additional[j]*=window[j];
+
+ for(j=0;j<n/2;j++)
+ pcm[j]=pcmori[j]-pcm[j]*quant[j];
+ mdct_backward(b->transform[vb->W][0],pcm,pcm);
+ for(j=0;j<n;j++)
+ pcm[j]*=window[j];
+
+ /* weighted compare twixt original and quantized mdct output */
+ for(j=0;j<n;j++){
+ den+=(pcm[j]*pcm[j]);
+ num+=(additional[j]*additional[j]);
+ }
+
+ num=sqrt(num);
+ den=sqrt(den);
+
+ }
+
+ look->floor_func[submap]->
+ forward2(vb,look->floor_look[submap],
+ nonzero[i],den==0.f?0.:num/den,vbb_flr+i);
+
+ }
+ }
+
+ bitbuf_pack(&vb->opb,&vbb_res);
+
+ look->lastframe=vb->sequence;
+ return(0);
+}
+
+static int mapping0_inverse(vorbis_block *vb,vorbis_look_mapping *l){
+ vorbis_dsp_state *vd=vb->vd;
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=vi->codec_setup;
+ backend_lookup_state *b=vd->backend_state;
+ vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
+ vorbis_info_mapping0 *info=look->map;
+ vorbis_info_mode *mode=look->mode;
+ int i,j;
+ long n=vb->pcmend=ci->blocksizes[vb->W];
+
+ float *window=b->window[vb->W][vb->lW][vb->nW][mode->windowtype];
+ float **pcmbundle=alloca(sizeof(float *)*vi->channels);
+ int *nonzero=alloca(sizeof(int)*vi->channels);
+
+ /* time domain information decode (note that applying the
+ information would have to happen later; we'll probably add a
+ function entry to the harness for that later */
+ /* NOT IMPLEMENTED */
+
+ /* recover the spectral envelope; store it in the PCM vector for now */
+ for(i=0;i<vi->channels;i++){
+ float *pcm=vb->pcm[i];
+ int submap=info->chmuxlist[i];
+ nonzero[i]=look->floor_func[submap]->
+ inverse(vb,look->floor_look[submap],pcm);
+ _analysis_output("ifloor",seq+i,pcm,n/2,0,1);
+ }
+
+ /* recover the residue, apply directly to the spectral envelope */
+
+ for(i=0;i<info->submaps;i++){
+ int ch_in_bundle=0;
+ for(j=0;j<vi->channels;j++){
+ if(info->chmuxlist[j]==i && nonzero[j])
+ pcmbundle[ch_in_bundle++]=vb->pcm[j];
+ }
+
+ look->residue_func[i]->inverse(vb,look->residue_look[i],pcmbundle,ch_in_bundle);
+ }
+
+ /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
+ /* only MDCT right now.... */
+ for(i=0;i<vi->channels;i++){
+ float *pcm=vb->pcm[i];
+ _analysis_output("out",seq+i,pcm,n/2,0,1);
+ mdct_backward(b->transform[vb->W][0],pcm,pcm);
+ }
+
+ /* now apply the decoded pre-window time information */
+ /* NOT IMPLEMENTED */
+
+ /* window the data */
+ for(i=0;i<vi->channels;i++){
+ float *pcm=vb->pcm[i];
+ if(nonzero[i])
+ for(j=0;j<n;j++)
+ pcm[j]*=window[j];
+ else
+ for(j=0;j<n;j++)
+ pcm[j]=0.f;
+ _analysis_output("final",seq++,pcm,n,0,0);
+ }
+
+ /* now apply the decoded post-window time information */
+ /* NOT IMPLEMENTED */
+
+ /* all done! */
+ return(0);
+}
+
+/* export hooks */
+vorbis_func_mapping mapping0_exportbundle={
+ &mapping0_pack,&mapping0_unpack,&mapping0_look,&mapping0_copy_info,
+ &mapping0_free_info,&mapping0_free_look,&mapping0_forward,&mapping0_inverse
+};
+
+
+
diff --git a/lib/modes/mode_A.h b/lib/modes/mode_A.h
new file mode 100644
index 00000000..206fd76e
--- /dev/null
+++ b/lib/modes/mode_A.h
@@ -0,0 +1,300 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: predefined encoding modes
+ last mod: $Id: mode_A.h,v 1.7.2.1 2000/12/27 23:46:38 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_MODES_A_H_
+#define _V_MODES_A_H_
+
+#include <stdio.h>
+#include "vorbis/codec.h"
+#include "backends.h"
+
+#include "books/lsp12_0.vqh"
+#include "books/lsp30_0.vqh"
+
+#include "books/res0_128_128aux.vqh"
+#include "books/res0_128_1024aux.vqh"
+
+#include "books/res0_128_128_1.vqh"
+#include "books/res0_128_128_2.vqh"
+#include "books/res0_128_128_3.vqh"
+#include "books/res0_128_128_4.vqh"
+#include "books/res0_128_128_5.vqh"
+
+#include "books/res0_128_1024_1.vqh"
+#include "books/res0_128_1024_2.vqh"
+#include "books/res0_128_1024_3.vqh"
+#include "books/res0_128_1024_4.vqh"
+#include "books/res0_128_1024_5.vqh"
+#include "books/res0_128_1024_6.vqh"
+#include "books/res0_128_1024_7.vqh"
+#include "books/res0_128_1024_8.vqh"
+#include "books/res0_128_1024_9.vqh"
+
+
+static vorbis_info_psy _psy_set_A0={
+ 1,/*athp*/
+ 1,/*decayp*/
+
+ -100.,
+ -140.,
+
+ 8,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 2, /* nearDCp */
+ -40.f, /* nearDCdB */
+
+ 1,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*63*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*88*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*125*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*175*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*250*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*350*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*500*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*700*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*1000*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*1400*/
+ {-40.,-40.,-40.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*2000*/
+ {-40.,-40.,-40.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*2800*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*4000*/
+ {-30.,-30.,-35.,-37.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*5600*/
+ {-20.,-25.,-30.,-35.,-35.,-50.,-60.,-70.,-80.,-90.,-100.}, /*8000*/
+ {-20.,-25.,-30.,-33.,-35.,-45.,-55.,-65.,-75.,-90.,-100.}, /*11500*/
+ {-20.,-24.,-26.,-32.,-35.,-45.,-55.,-65.,-75.,-90.,-100.}, /*16000*/
+ },
+
+ 1,/* peakattp */
+ {{-14.,-16.,-18.,-19.,-20.,-21.,-22.,-22.,-28.,-28.,-28.}, /*63*/
+ {-14.,-16.,-18.,-19.,-20.,-21.,-22.,-22.,-28.,-28.,-28.}, /*88*/
+ {-14.,-16.,-18.,-19.,-20.,-21.,-22.,-22.,-28.,-28.,-28.}, /*125*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-18.,-28.,-28.,-28.}, /*175*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-18.,-28.,-28.,-28.}, /*250*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-18.,-28.,-28.,-28.}, /*350*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-28.,-28.,-28.,-28.}, /*500*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*700*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*1000*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*1400*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*2000*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*2400*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*4000*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*5600*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-16.,-17.}, /*8000*/
+ { -6., -7., -9., -9., -9., -9.,-10.,-11.,-12.,-13.,-14.}, /*11500*/
+ { -6., -6., -9., -9., -9., -9., -9., -9.,-10.,-11.,-12.}, /*16000*/
+ },
+
+ 1,/*noisemaskp */
+ -40.f, /* noisemaxsupp */
+ .5, /* low window */
+ .5, /* high window */
+ 5,
+ 5,
+ {.000, /*63*/
+ .000, /*88*/
+ .000, /*125*/
+ .000, /*175*/
+ .000, /*250*/
+ .000, /*350*/
+ .000, /*500*/
+ .500, /*700*/
+ .600, /*1000*/
+ .600, /*1400*/
+ .500, /*2000*/
+ .500, /*2800*/
+ .750, /*4000*/
+ .850, /*5600*/
+ .900, /*8000*/
+ .900, /*11500*/
+ .950, /*16000*/
+ },
+
+ 100.,
+
+ -0., -.004 /* attack/decay control */
+};
+
+static vorbis_info_psy _psy_set_A={
+ 1,/*athp*/
+ 1,/*decayp*/
+
+ -100.f,
+ -140.f,
+
+ 8,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 1, /* nearDCp */
+ -40.f, /* nearDCdB */
+
+ 1,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*63*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*88*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*125*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/
+ {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2000*/
+ {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2800*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/
+ {-30.f,-30.f,-35.f,-37.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/
+ {-20.f,-25.f,-30.f,-35.f,-35.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/
+ {-20.f,-25.f,-30.f,-33.f,-35.f,-45.f,-55.f,-65.f,-75.f,-90.f,-100.f}, /*11500*/
+ {-20.f,-24.f,-26.f,-32.f,-35.f,-45.f,-55.f,-65.f,-75.f,-90.f,-100.f}, /*16000*/
+ },
+
+ 1,/* peakattp */
+ {{-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f},
+ {-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f,-30.f}},
+
+ 1, /* noisemaskp */
+ -40.f, /* noisemaxsupp */
+ .5, /* low window */
+ .5, /* high window */
+ 25,
+ 25,
+ {.000, /*63*/
+ .000, /*88*/
+ .000, /*125*/
+ .000, /*175*/
+ .000, /*250*/
+ .000, /*350*/
+ .000, /*500*/
+ .500, /*700*/
+ .600, /*1000*/
+ .600, /*1400*/
+ .500, /*2000*/
+ .500, /*2800*/
+ .750, /*4000*/
+ .850, /*5600*/
+ .900, /*8000*/
+ .900, /*11500*/
+ .950, /*16000*/
+ },
+
+ 100.f,
+
+ -0.f, -.004f /* attack/decay control */
+};
+
+/* with GNUisms, this could be short and readable. Oh well */
+static vorbis_info_time0 _time_set0A={0};
+static vorbis_info_floor0 _floor_set0A={12, 44100, 64, 12,150, 1, {0} };
+static vorbis_info_floor0 _floor_set1A={30, 44100, 256, 12,150, 1, {1} };
+static vorbis_info_residue0 _residue_set0A={0,128, 32,6,2,
+ {0,1,1,1,1,1},
+ {4,5,6,7,8},
+
+ {0,99999,9999,9999,9999},
+ {99.f,1.5f,2.5f,6.5f,12.5f},
+ {5,5,5,5,5},
+ {99,99,99,99,99}};
+
+static vorbis_info_residue0 _residue_set1A={0,1024, 32,10,3,
+ {0,1,1,1,1,1,1,1,1,1},
+ {9,10,11,12,13,14,15,16,17},
+
+ {0,8,9999,17,9999,
+ 28,9999,9999,9999},
+ {99.f,1.5f,1.5f,2.5f,2.5f,
+ 4.f,4.f,6.5f,12.5f},
+ {5,5,5,5,5,5,5,5,5},
+ {99,99,99,99,99,99,99,99,99}};
+
+static vorbis_info_mapping0 _mapping_set0A={1, {0,0}, {0}, {0}, {0}, {0}};
+static vorbis_info_mapping0 _mapping_set1A={1, {0,0}, {0}, {1}, {1}, {1}};
+static vorbis_info_mode _mode_set0A={0,0,0,0};
+static vorbis_info_mode _mode_set1A={1,0,0,1};
+
+/* CD quality stereo, no channel coupling */
+codec_setup_info info_A={
+
+ /* smallblock, largeblock */
+ {256, 2048},
+ /* modes,maps,times,floors,residues,books,psys */
+ 2, 2, 1, 2, 2, 18, 2,
+ /* modes */
+ {&_mode_set0A,&_mode_set1A},
+ /* maps */
+ {0,0},{&_mapping_set0A,&_mapping_set1A},
+ /* times */
+ {0,0},{&_time_set0A},
+ /* floors */
+ {0,0},{&_floor_set0A,&_floor_set1A},
+ /* residue */
+ {0,0},{&_residue_set0A,&_residue_set1A},
+ /* books */
+ {&_vq_book_lsp12_0, /* 0 */
+ &_vq_book_lsp30_0, /* 1 */
+
+ &_huff_book_res0_128_128aux,
+ &_huff_book_res0_128_1024aux,
+
+ &_vq_book_res0_128_128_1,
+ &_vq_book_res0_128_128_2,
+ &_vq_book_res0_128_128_3,
+ &_vq_book_res0_128_128_4,
+ &_vq_book_res0_128_128_5,
+
+ &_vq_book_res0_128_1024_1,
+ &_vq_book_res0_128_1024_2,
+ &_vq_book_res0_128_1024_3,
+ &_vq_book_res0_128_1024_4,
+ &_vq_book_res0_128_1024_5,
+ &_vq_book_res0_128_1024_6,
+ &_vq_book_res0_128_1024_7,
+ &_vq_book_res0_128_1024_8,
+ &_vq_book_res0_128_1024_9,
+
+ },
+ /* psy */
+ {&_psy_set_A0,&_psy_set_A},
+ /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
+ 256, 32.f, -32.f, -96.f
+};
+
+#define PREDEF_INFO_MAX 0
+
+#endif
diff --git a/lib/modes/mode_AA.h b/lib/modes/mode_AA.h
new file mode 100644
index 00000000..6fa684b5
--- /dev/null
+++ b/lib/modes/mode_AA.h
@@ -0,0 +1,292 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: predefined encoding modes
+ last mod: $Id: mode_AA.h,v 1.3.2.1 2000/12/27 23:46:38 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_MODES_AA_H_
+#define _V_MODES_AA_H_
+
+#include <stdio.h>
+#include "vorbis/codec.h"
+#include "backends.h"
+
+#include "books/lsp12_0.vqh"
+#include "books/lsp30_0.vqh"
+
+#include "books/res0_96_128aux.vqh"
+
+#include "books/res0_96_128_1.vqh"
+#include "books/res0_96_128_2.vqh"
+#include "books/res0_96_128_3.vqh"
+#include "books/res0_96_128_4.vqh"
+#include "books/res0_96_128_5.vqh"
+
+#include "books/res0_96_1024aux.vqh"
+
+#include "books/res0_96_1024_1.vqh"
+#include "books/res0_96_1024_2.vqh"
+#include "books/res0_96_1024_3.vqh"
+#include "books/res0_96_1024_4.vqh"
+#include "books/res0_96_1024_5.vqh"
+#include "books/res0_96_1024_6.vqh"
+#include "books/res0_96_1024_7.vqh"
+
+static vorbis_info_psy _psy_set_AA0={
+ 1,/*athp*/
+ 1,/*decayp*/
+ 1,/*smoothp*/
+
+ -100.,
+ -140.,
+
+ 8,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 1,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*63*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*88*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*125*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*175*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*250*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*350*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*500*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*700*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*1000*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*1400*/
+ {-40.,-40.,-40.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*2000*/
+ {-40.,-40.,-40.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*2800*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*4000*/
+ {-30.,-30.,-35.,-37.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*5600*/
+ {-20.,-25.,-30.,-35.,-35.,-50.,-60.,-70.,-80.,-90.,-100.}, /*8000*/
+ {-20.,-25.,-30.,-33.,-35.,-45.,-55.,-65.,-75.,-90.,-100.}, /*11500*/
+ {-20.,-24.,-26.,-32.,-35.,-45.,-55.,-65.,-75.,-90.,-100.}, /*16000*/
+ },
+
+ 1,/* peakattp */
+ {{-14.,-16.,-18.,-19.,-20.,-21.,-22.,-22.,-22.,-22.,-22.}, /*63*/
+ {-14.,-16.,-18.,-19.,-20.,-21.,-22.,-22.,-22.,-22.,-22.}, /*88*/
+ {-14.,-16.,-18.,-19.,-20.,-21.,-22.,-22.,-22.,-22.,-22.}, /*125*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*175*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*250*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*350*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*500*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*700*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*1000*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*1400*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*2000*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*2800*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*4000*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*5600*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-16.,-17.}, /*8000*/
+ { -6., -7., -9., -9., -9., -9.,-10.,-11.,-12.,-13.,-14.}, /*11500*/
+ { -6., -6., -9., -9., -9., -9., -9., -9.,-10.,-11.,-12.}, /*16000*/
+ },
+
+ 1,/*noisemaskp */
+ .5, /* low window */
+ .5, /* high window */
+ 15,
+ 15,
+ {.000, /*63*/
+ .000, /*88*/
+ .000, /*125*/
+ .000, /*175*/
+ .000, /*250*/
+ .000, /*350*/
+ .000, /*500*/
+ .500, /*700*/
+ .500, /*1000*/
+ .500, /*1400*/
+ .500, /*2000*/
+ .500, /*2800*/
+ .500, /*4000*/
+ .500, /*5600*/
+ .650, /*8000*/
+ .650, /*11500*/
+ .600, /*16000*/
+ },
+
+ 95.,
+
+ -0., -.004 /* attack/decay control */
+};
+
+static vorbis_info_psy _psy_set_AA={
+ 1,/*athp*/
+ 1,/*decayp*/
+ 1,/*smoothp*/
+
+ -100.f,
+ -140.f,
+
+ 8,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 1,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*63*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*88*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*125*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/
+ {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2000*/
+ {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2800*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/
+ {-30.f,-30.f,-35.f,-37.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/
+ {-20.f,-25.f,-30.f,-35.f,-35.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/
+ {-20.f,-25.f,-30.f,-33.f,-35.f,-45.f,-55.f,-65.f,-75.f,-90.f,-100.f}, /*11500*/
+ {-20.f,-24.f,-26.f,-32.f,-35.f,-45.f,-55.f,-65.f,-75.f,-90.f,-100.f}, /*16000*/
+ },
+
+ 1,/* peakattp */
+ {{-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*63*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*88*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*125*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*175*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*250*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*350*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*500*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*700*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*1000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*1400*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*2000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*2800*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*4000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*5600*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-16.f,-17.f}, /*8000*/
+ { -6.f, -7.f, -9.f, -9.f, -9.f, -9.f,-10.f,-11.f,-12.f,-13.f,-14.f}, /*11500*/
+ { -6.f, -6.f, -9.f, -9.f, -9.f, -9.f, -9.f, -9.f,-10.f,-11.f,-12.f}, /*16000*/
+ },
+
+ 1,/*noisemaskp */
+ .5, /* low window */
+ .5, /* high window */
+ 25,
+ 25,
+ {.000, /*63*/
+ .000, /*88*/
+ .000, /*125*/
+ .000, /*175*/
+ .000, /*250*/
+ .000, /*350*/
+ .000, /*500*/
+ .500, /*700*/
+ .500, /*1000*/
+ .500, /*1400*/
+ .500, /*2000*/
+ .500, /*2800*/
+ .700, /*4000*/
+ .800, /*5600*/
+ .850, /*8000*/
+ .850, /*11500*/
+ .900, /*16000*/
+ },
+
+ 95.f,
+
+ -0.f, -.004f /* attack/decay control */
+};
+
+
+/* with GNUisms, this could be short and readable. Oh well */
+static vorbis_info_time0 _time_set0AA={0};
+static vorbis_info_floor0 _floor_set0AA={12, 44100, 64, 12,150, 1, {0} };
+static vorbis_info_floor0 _floor_set1AA={30, 44100, 256, 12,150, 1, {1} };
+static vorbis_info_residue0 _residue_set0AA={0,128, 32,6,2,
+ {0,1,1,1,1,1},
+ {4,5,6,7,8},
+
+ {0,99999,9999,9999,9999},
+ {99.f,1.5f,2.5f,6.5f,12.5f},
+ {5,5,5,5,5},
+ {99,99,99,99,99}};
+
+
+static vorbis_info_residue0 _residue_set1AA={0,1024, 32,8,3,
+ {0,1,1,1,1,1,1,1},
+ {9,10,11,12,13,14,15},
+
+ {0,9,9999,21,9999,
+ 9999,9999,9999},
+ {99.f,2.f,2.f,4.f,4.f,9.5f,15.5f},
+ {5,5,5,5,5,5,5},
+ {99,99,99,99,99,99,99}};
+
+static vorbis_info_mapping0 _mapping_set0AA={1, {0,0}, {0}, {0}, {0}, {0}};
+static vorbis_info_mapping0 _mapping_set1AA={1, {0,0}, {0}, {1}, {1}, {1}};
+static vorbis_info_mode _mode_set0AA={0,0,0,0};
+static vorbis_info_mode _mode_set1AA={1,0,0,1};
+
+/* CD quality stereo, no channel coupling */
+codec_setup_info info_AA={
+
+ /* smallblock, largeblock */
+ {256, 2048},
+ /* modes,maps,times,floors,residues,books,psys */
+ 2, 2, 1, 2, 2, 16, 2,
+ /* modes */
+ {&_mode_set0AA,&_mode_set1AA},
+ /* maps */
+ {0,0},{&_mapping_set0AA,&_mapping_set1AA},
+ /* times */
+ {0,0},{&_time_set0AA},
+ /* floors */
+ {0,0},{&_floor_set0AA,&_floor_set1AA},
+ /* residue */
+ {0,0},{&_residue_set0AA,&_residue_set1AA},
+ /* books */
+ {&_vq_book_lsp12_0, /* 0 */
+ &_vq_book_lsp30_0, /* 1 */
+
+ &_huff_book_res0_96_128aux,
+ &_huff_book_res0_96_1024aux,
+
+ &_vq_book_res0_96_128_1,
+ &_vq_book_res0_96_128_2,
+ &_vq_book_res0_96_128_3,
+ &_vq_book_res0_96_128_4,
+ &_vq_book_res0_96_128_5,
+
+ &_vq_book_res0_96_1024_1,
+ &_vq_book_res0_96_1024_2,
+ &_vq_book_res0_96_1024_3,
+ &_vq_book_res0_96_1024_4,
+ &_vq_book_res0_96_1024_5,
+ &_vq_book_res0_96_1024_6,
+ &_vq_book_res0_96_1024_7,
+
+ },
+ /* psy */
+ {&_psy_set_AA0,&_psy_set_AA},
+ /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
+ 256, 32.f, 6.f, -96.f
+};
+
+#define PREDEF_INFO_MAX 0
+
+#endif
diff --git a/lib/modes/mode_B.h b/lib/modes/mode_B.h
new file mode 100644
index 00000000..ad3025b3
--- /dev/null
+++ b/lib/modes/mode_B.h
@@ -0,0 +1,210 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: predefined encoding modes
+ last mod: $Id: mode_B.h,v 1.6.2.1 2000/12/27 23:46:38 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_MODES_B_H_
+#define _V_MODES_B_H_
+
+#include <stdio.h>
+#include "vorbis/codec.h"
+#include "backends.h"
+
+#include "books/lsp12_0.vqh"
+#include "books/lsp30_0.vqh"
+
+#include "books/res0_160_128aux.vqh"
+#include "books/res0_160_1024aux.vqh"
+
+#include "books/res0_160_128_1.vqh"
+#include "books/res0_160_128_2.vqh"
+#include "books/res0_160_128_3.vqh"
+#include "books/res0_160_128_4.vqh"
+#include "books/res0_160_128_5.vqh"
+
+#include "books/res0_160_1024_1.vqh"
+#include "books/res0_160_1024_2.vqh"
+#include "books/res0_160_1024_3.vqh"
+#include "books/res0_160_1024_4.vqh"
+#include "books/res0_160_1024_5.vqh"
+#include "books/res0_160_1024_6.vqh"
+#include "books/res0_160_1024_7.vqh"
+#include "books/res0_160_1024_8.vqh"
+#include "books/res0_160_1024_9.vqh"
+
+static vorbis_info_psy _psy_set_B={
+ 1,/*athp*/
+ 1,/*decayp*/
+ 1,/*smoothp*/
+
+ -100.f,
+ -140.f,
+
+ 8,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 1,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*63*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*88*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*125*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/
+ {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2000*/
+ {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2800*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/
+ {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/
+ {-30.f,-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/
+ {-30.f,-30.f,-35.f,-33.f,-35.f,-45.f,-55.f,-65.f,-75.f,-90.f,-100.f}, /*11500*/
+ {-30.f,-28.f,-30.f,-32.f,-35.f,-45.f,-55.f,-65.f,-75.f,-90.f,-100.f}, /*16000*/
+ },
+
+ 1,/* peakattp */
+ {{-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*63*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*88*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*125*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-28.f,-28.f,-28.f}, /*175*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-28.f,-28.f,-28.f}, /*250*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-28.f,-28.f,-28.f}, /*350*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-28.f,-28.f,-28.f}, /*500*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*700*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*1000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*1400*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*2000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*2800*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*4000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*5600*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-16.f,-17.f}, /*8000*/
+ { -6.f, -7.f, -9.f, -9.f, -9.f, -9.f,-10.f,-11.f,-12.f,-13.f,-14.f}, /*11500*/
+ { -6.f, -6.f, -9.f, -9.f, -9.f, -9.f, -9.f, -9.f,-10.f,-11.f,-12.f}, /*16000*/
+ },
+
+ 1,/*noisemaskp */
+ .5, /* low window */
+ .5, /* high window */
+ 25,
+ 25,
+ {.000, /*63*/
+ .000, /*88*/
+ .000, /*125*/
+ .000, /*175*/
+ .000, /*250*/
+ .000, /*350*/
+ .000, /*500*/
+ .500, /*700*/
+ .500, /*1000*/
+ .500, /*1400*/
+ .500, /*2000*/
+ .500, /*2800*/
+ .700, /*4000*/
+ .800, /*5600*/
+ .850, /*8000*/
+ .850, /*11500*/
+ .900, /*16000*/
+ },
+
+ 110.f,
+
+ -3.f, -.004f /* attack/decay control */
+};
+
+/* with GNUisms, this could be short and readable. Oh well */
+static vorbis_info_time0 _time_set0B={0};
+static vorbis_info_floor0 _floor_set0B={12, 44100, 64, 12,150, 1, {0} };
+static vorbis_info_floor0 _floor_set1B={30, 44100, 256, 12,150, 1, {1} };
+static vorbis_info_residue0 _residue_set0B={0,128, 32,6,2,
+ {0,1,1,1,1,1},
+ {4,5,6,7,8},
+
+ {0,99999,9999,9999,9999},
+ {99.f,1.5f,2.5f,6.5f,12.5f},
+ {5,5,5,5,5},
+ {99,99,99,99,99}};
+
+static vorbis_info_residue0 _residue_set1B={0,1024, 32,10,3,
+ {0,1,1,1,1,1,1,1,1,1},
+ {9,10,11,12,13,14,15,16,17},
+
+ {0,8,9999,17,9999,
+ 22,9999,9999,9999},
+ {99.f,1.5f,1.5f,2.5f,2.5f,
+ 4.f,4.f,6.5f,12.5f},
+ {5,5,5,5,5,5,5,5,5},
+ {99,99,99,99,99,99,99,99,99}};
+
+static vorbis_info_mapping0 _mapping_set0B={1, {0,0}, {0}, {0}, {0}, {0}};
+static vorbis_info_mapping0 _mapping_set1B={1, {0,0}, {0}, {1}, {1}, {0}};
+static vorbis_info_mode _mode_set0B={0,0,0,0};
+static vorbis_info_mode _mode_set1B={1,0,0,1};
+
+/* CD quality stereo, no channel coupling */
+codec_setup_info info_B={
+
+ /* smallblock, largeblock */
+ {256, 2048},
+ /* modes,maps,times,floors,residues,books,psys */
+ 2, 2, 1, 2, 2, 18, 1,
+ /* modes */
+ {&_mode_set0B,&_mode_set1B},
+ /* maps */
+ {0,0},{&_mapping_set0B,&_mapping_set1B},
+ /* times */
+ {0,0},{&_time_set0B},
+ /* floors */
+ {0,0},{&_floor_set0B,&_floor_set1B},
+ /* residue */
+ {0,0},{&_residue_set0B,&_residue_set1B},
+ /* books */
+ {&_vq_book_lsp12_0, /* 0 */
+ &_vq_book_lsp30_0, /* 1 */
+
+ &_huff_book_res0_160_128aux,
+ &_huff_book_res0_160_1024aux,
+
+ &_vq_book_res0_160_128_1,
+ &_vq_book_res0_160_128_2,
+ &_vq_book_res0_160_128_3,
+ &_vq_book_res0_160_128_4,
+ &_vq_book_res0_160_128_5,
+
+ &_vq_book_res0_160_1024_1,
+ &_vq_book_res0_160_1024_2,
+ &_vq_book_res0_160_1024_3,
+ &_vq_book_res0_160_1024_4,
+ &_vq_book_res0_160_1024_5,
+ &_vq_book_res0_160_1024_6,
+ &_vq_book_res0_160_1024_7,
+ &_vq_book_res0_160_1024_8,
+ &_vq_book_res0_160_1024_9,
+
+ },
+ /* psy */
+ {&_psy_set_B},
+ /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
+ 256, 32.f, 6.f, -96.f
+};
+
+#define PREDEF_INFO_MAX 0
+
+#endif
diff --git a/lib/modes/mode_C.h b/lib/modes/mode_C.h
new file mode 100644
index 00000000..97307d20
--- /dev/null
+++ b/lib/modes/mode_C.h
@@ -0,0 +1,283 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: predefined encoding modes
+ last mod: $Id: mode_C.h,v 1.6.2.1 2000/12/27 23:46:38 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_MODES_C_H_
+#define _V_MODES_C_H_
+
+#include <stdio.h>
+#include "vorbis/codec.h"
+#include "backends.h"
+
+#include "books/lsp12_0.vqh"
+#include "books/lsp30_0.vqh"
+
+#include "books/res0_192_128aux.vqh"
+#include "books/res0_192_1024aux.vqh"
+
+#include "books/res0_192_128_1.vqh"
+#include "books/res0_192_128_2.vqh"
+#include "books/res0_192_128_3.vqh"
+#include "books/res0_192_128_4.vqh"
+#include "books/res0_192_128_5.vqh"
+
+#include "books/res0_192_1024_1.vqh"
+#include "books/res0_192_1024_2.vqh"
+#include "books/res0_192_1024_3.vqh"
+#include "books/res0_192_1024_4.vqh"
+#include "books/res0_192_1024_5.vqh"
+
+static vorbis_info_psy _psy_set_C0={
+ 1,/*athp*/
+ 0,/*decayp*/
+ 1,/*smoothp*/
+
+ -100.f,
+ -140.f,
+
+ 8,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 0,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*63*/
+ {-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*88*/
+ {-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*125*/
+ {-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*175*/
+ {-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*250*/
+ {-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*350*/
+ {-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*500*/
+ {-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*700*/
+ {-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*1000*/
+ {-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*1400*/
+ {-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*2000*/
+ {-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*2800*/
+ {-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*4000*/
+ {-30.f,-30.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*5600*/
+ {-30.f,-30.f,-35.f,-35.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f,-110.f}, /*8000*/
+ {-30.f,-30.f,-35.f,-33.f,-45.f,-55.f,-65.f,-75.f,-85.f,-100.f,-110.f}, /*11500*/
+ {-30.f,-28.f,-30.f,-32.f,-45.f,-55.f,-65.f,-75.f,-85.f,-100.f,-110.f}, /*16000*/
+ },
+
+ 1,/* peakattp */
+ {{-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*63*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*88*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*125*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-28.f,-28.f,-28.f}, /*175*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-28.f,-28.f,-28.f}, /*250*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-28.f,-28.f,-28.f}, /*350*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-28.f,-28.f,-28.f}, /*500*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*700*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*1000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*1400*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*2000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*2800*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*4000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*5600*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-16.f,-17.f}, /*8000*/
+ { -6.f, -7.f, -9.f, -9.f, -9.f, -9.f,-10.f,-11.f,-12.f,-13.f,-14.f}, /*11500*/
+ { -6.f, -6.f, -9.f, -9.f, -9.f, -9.f, -9.f, -9.f,-10.f,-11.f,-12.f}, /*16000*/
+ },
+
+ 1,/*noisemaskp */
+ .5, /* low window */
+ .5, /* high window */
+ 25,
+ 25,
+ {.000, /*63*/
+ .000, /*88*/
+ .000, /*125*/
+ .000, /*175*/
+ .000, /*250*/
+ .000, /*350*/
+ .000, /*500*/
+ .500, /*700*/
+ .500, /*1000*/
+ .500, /*1400*/
+ .500, /*2000*/
+ .500, /*2800*/
+ .700, /*4000*/
+ .800, /*5600*/
+ .850, /*8000*/
+ .850, /*11500*/
+ .900, /*16000*/
+ },
+
+ 100.f,
+
+ -6.f, -.006f /* attack/decay control */
+};
+
+static vorbis_info_psy _psy_set_C1={
+ 1,/*athp*/
+ 0,/*decayp*/
+ 1,/*smoothp*/
+
+ -100.f,
+ -140.f,
+
+ 8,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 1,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*63*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*88*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*125*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1400*/
+ {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2000*/
+ {-40.f,-40.f,-40.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*2800*/
+ {-30.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/
+ {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/
+ {-30.f,-30.f,-35.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/
+ {-30.f,-30.f,-35.f,-33.f,-35.f,-45.f,-55.f,-65.f,-75.f,-90.f,-100.f}, /*11500*/
+ {-30.f,-28.f,-30.f,-32.f,-35.f,-45.f,-55.f,-65.f,-75.f,-90.f,-100.f}, /*16000*/
+ },
+
+ 1,/* peakattp */
+ {{-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-28.f,-28.f}, /*63*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-28.f,-28.f}, /*88*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-28.f,-28.f}, /*125*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-18.f,-18.f,-20.f}, /*175*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-18.f,-18.f,-20.f}, /*250*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-18.f,-18.f,-20.f}, /*350*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-18.f,-18.f,-20.f}, /*500*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*700*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*1000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*1400*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*2000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*2800*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*4000*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-18.f,-20.f}, /*5600*/
+ { -7.f, -8.f, -9.f,-10.f,-10.f,-11.f,-12.f,-13.f,-15.f,-16.f,-17.f}, /*8000*/
+ { -6.f, -7.f, -9.f, -9.f, -9.f, -9.f,-10.f,-11.f,-12.f,-13.f,-14.f}, /*11500*/
+ { -6.f, -6.f, -9.f, -9.f, -9.f, -9.f, -9.f, -9.f,-10.f,-11.f,-12.f}, /*16000*/
+ },
+
+ 1,/*noisemaskp */
+ .5, /* low window */
+ .5, /* high window */
+ 25,
+ 25,
+ {.000, /*63*/
+ .000, /*88*/
+ .000, /*125*/
+ .000, /*175*/
+ .000, /*250*/
+ .000, /*350*/
+ .000, /*500*/
+ .500, /*700*/
+ .500, /*1000*/
+ .500, /*1400*/
+ .500, /*2000*/
+ .500, /*2800*/
+ .700, /*4000*/
+ .800, /*5600*/
+ .850, /*8000*/
+ .850, /*11500*/
+ .900, /*16000*/
+ },
+ 110.f,
+
+ -6.f, -.006f /* attack/decay control */
+};
+
+/* with GNUisms, this could be short and readable. Oh well */
+static vorbis_info_time0 _time_set0C={0};
+static vorbis_info_floor0 _floor_set0C={12, 44100, 64, 12,150, 1, {0} };
+static vorbis_info_floor0 _floor_set1C={30, 44100, 256, 12,150, 1, {1} };
+static vorbis_info_residue0 _residue_set0C={0,128, 32,6,2,
+ {0,1,1,1,1,1},
+ {4,5,6,7,8},
+
+ {0,99999,9999,9999,9999},
+ {99.f,1.5f,2.5f,6.5f,12.5f},
+ {5,5,5,5,5},
+ {99,99,99,99,99}};
+
+static vorbis_info_residue0 _residue_set1C={0,1024, 32,6,3,
+ {0,1,1,1,1,1},
+ {9,10,11,12,13},
+
+ {0,99999,9999,9999,9999},
+ {99.f,1.5f,2.5f,6.5f,12.5f},
+ {5,5,5,5,5},
+ {99,99,99,99,99}};
+
+static vorbis_info_mapping0 _mapping_set0C={1, {0,0}, {0}, {0}, {0}, {0}};
+static vorbis_info_mapping0 _mapping_set1C={1, {0,0}, {0}, {1}, {1}, {1}};
+static vorbis_info_mode _mode_set0C={0,0,0,0};
+static vorbis_info_mode _mode_set1C={1,0,0,1};
+
+/* CD quality stereo, no channel coupling */
+codec_setup_info info_C={
+
+ /* smallblock, largeblock */
+ {256, 2048},
+ /* modes,maps,times,floors,residues,books,psys */
+ 2, 2, 1, 2, 2, 14, 2,
+ /* modes */
+ {&_mode_set0C,&_mode_set1C},
+ /* maps */
+ {0,0},{&_mapping_set0C,&_mapping_set1C},
+ /* times */
+ {0,0},{&_time_set0C},
+ /* floors */
+ {0,0},{&_floor_set0C,&_floor_set1C},
+ /* residue */
+ {0,0},{&_residue_set0C,&_residue_set1C},
+ /* books */
+ {&_vq_book_lsp12_0, /* 0 */
+ &_vq_book_lsp30_0, /* 1 */
+
+ &_huff_book_res0_192_128aux,
+ &_huff_book_res0_192_1024aux,
+
+ &_vq_book_res0_192_128_1,
+ &_vq_book_res0_192_128_2,
+ &_vq_book_res0_192_128_3,
+ &_vq_book_res0_192_128_4,
+ &_vq_book_res0_192_128_5,
+
+ &_vq_book_res0_192_1024_1,
+ &_vq_book_res0_192_1024_2,
+ &_vq_book_res0_192_1024_3,
+ &_vq_book_res0_192_1024_4,
+ &_vq_book_res0_192_1024_5,
+
+ },
+ /* psy */
+ {&_psy_set_C0,&_psy_set_C1},
+ /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
+ 256, 24.f, 6.f, -96.f
+};
+
+#define PREDEF_INFO_MAX 0
+
+#endif
diff --git a/lib/modes/mode_D.h b/lib/modes/mode_D.h
new file mode 100644
index 00000000..1a7dbf9c
--- /dev/null
+++ b/lib/modes/mode_D.h
@@ -0,0 +1,236 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: predefined encoding modes
+ last mod: $Id: mode_D.h,v 1.7.2.1 2000/12/27 23:46:38 xiphmont Exp $
+
+ ********************************************************************/
+
+/* this is really a freeform VBR mode. It roughly centers on 256 kbps stereo */
+
+#ifndef _V_MODES_D_H_
+#define _V_MODES_D_H_
+
+#include <stdio.h>
+#include "vorbis/codec.h"
+#include "backends.h"
+
+#include "books/lsp12_0.vqh"
+#include "books/lsp30_0.vqh"
+
+#include "books/res0_256_128aux.vqh"
+#include "books/res0_256_1024aux.vqh"
+
+#include "books/res0_256_128_1.vqh"
+#include "books/res0_256_128_2.vqh"
+#include "books/res0_256_128_3.vqh"
+#include "books/res0_256_128_4.vqh"
+#include "books/res0_256_128_5.vqh"
+
+#include "books/res0_256_1024_1.vqh"
+#include "books/res0_256_1024_2.vqh"
+#include "books/res0_256_1024_3.vqh"
+#include "books/res0_256_1024_4.vqh"
+#include "books/res0_256_1024_5.vqh"
+
+static vorbis_info_psy _psy_set_D0 ={
+ 1,/*athp*/
+ 0,/*decayp*/
+ 1,/*smoothp*/
+
+ -100.f,
+ -140.f,
+
+ 8,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 0,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{0}},
+
+ 1,/* peakattp */
+ {{-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*63*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*88*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*125*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*175*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*250*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*350*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*500*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*700*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*1000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*1400*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*2000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*2800*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*4000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*5600*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*8000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*11500*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*16000*/
+ },
+
+ 0,/*noisemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ .5,
+ .5,
+ 25,
+ 25,
+ {0},
+
+ 110.f,
+
+ -0.f, -.004f /* attack/decay control */
+};
+static vorbis_info_psy _psy_set_D1 ={
+ 1,/*athp*/
+ 0,/*decayp*/
+ 1,/*smoothp*/
+
+ -100.f,
+ -140.f,
+
+ 8,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 1,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*63*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*88*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*125*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*175*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*250*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*350*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*500*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*700*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*1000*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*1400*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*2000*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*2800*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*4000*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*5600*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*8000*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*11500*/
+ {-40.f,-40.f,-40.f,-45.f,-45.f,-55.f,-65.f,-75.f,-85.f,-95.f,-105.f}, /*16000*/
+ },
+
+ 1,/* peakattp */
+ {{-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*63*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*88*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*125*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*175*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*250*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*350*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-28.f}, /*500*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*700*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*1000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*1400*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*2000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*2800*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*4000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*5600*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*8000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*11500*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-22.f,-22.f}, /*16000*/
+ },
+
+ 0,/*noisemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ .5,
+ .5,
+ 25,
+ 25,
+ {0},
+
+ 110.f,
+
+ -0.f, -.004f /* attack/decay control */
+};
+
+/* with GNUisms, this could be short and readable. Oh well */
+static vorbis_info_time0 _time_set0_256={0};
+static vorbis_info_floor0 _floor_set0_256={12, 44100, 64, 12,150, 1, {0} };
+static vorbis_info_floor0 _floor_set1_256={30, 44100, 256, 12,150, 1, {1} };
+static vorbis_info_residue0 _residue_set0_256={0,128, 32,6,2,
+ {0,1,1,1,1,1},
+ {4,5,6,7,8},
+
+ {0,9999,9999,9999,9999},
+ {99.f,2.5f,6.5f,15.5f,29.5f},
+ {5,5,5,5,5},
+ {99,99,99,99,99}};
+
+static vorbis_info_residue0 _residue_set1_256={0,1024, 32,6,3,
+ {0,1,1,1,1,1},
+ {9,10,11,12,13},
+
+ {0,9999,9999,9999,9999},
+ {99.f,2.5f,6.5f,15.5f,29.5f},
+ {5,5,5,5,5},
+ {99,99,99,99,99}};
+
+static vorbis_info_mapping0 _mapping_set0_256={1, {0,0}, {0}, {0}, {0}, {0}};
+static vorbis_info_mapping0 _mapping_set1_256={1, {0,0}, {0}, {1}, {1}, {1}};
+static vorbis_info_mode _mode_set0_256={0,0,0,0};
+static vorbis_info_mode _mode_set1_256={1,0,0,1};
+
+/* CD quality stereo, no channel coupling */
+codec_setup_info info_D={
+
+ /* smallblock, largeblock */
+ {256, 2048},
+ /* modes,maps,times,floors,residues,books,psys */
+ 2, 2, 1, 2, 2, 14, 2,
+ /* modes */
+ {&_mode_set0_256,&_mode_set1_256},
+ /* maps */
+ {0,0},{&_mapping_set0_256,&_mapping_set1_256},
+ /* times */
+ {0,0},{&_time_set0_256},
+ /* floors */
+ {0,0},{&_floor_set0_256,&_floor_set1_256},
+ /* residue */
+ {0,0},{&_residue_set0_256,&_residue_set1_256},
+ /* books */
+ {&_vq_book_lsp12_0, /* 0 */
+ &_vq_book_lsp30_0, /* 1 */
+
+ &_huff_book_res0_256_128aux,
+ &_huff_book_res0_256_1024aux,
+
+ &_vq_book_res0_256_128_1,
+ &_vq_book_res0_256_128_2,
+ &_vq_book_res0_256_128_3,
+ &_vq_book_res0_256_128_4,
+ &_vq_book_res0_256_128_5,
+
+ &_vq_book_res0_256_1024_1,
+ &_vq_book_res0_256_1024_2,
+ &_vq_book_res0_256_1024_3,
+ &_vq_book_res0_256_1024_4,
+ &_vq_book_res0_256_1024_5,
+
+ },
+ /* psy */
+ {&_psy_set_D0,&_psy_set_D1},
+ /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
+ 256, 24.f, 6.f, -96.f
+};
+
+#define PREDEF_INFO_MAX 0
+
+#endif
diff --git a/lib/modes/mode_E.h b/lib/modes/mode_E.h
new file mode 100644
index 00000000..fab0a275
--- /dev/null
+++ b/lib/modes/mode_E.h
@@ -0,0 +1,169 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: predefined encoding modes
+ last mod: $Id: mode_E.h,v 1.4.2.1 2000/12/27 23:46:38 xiphmont Exp $
+
+ ********************************************************************/
+
+/* this is really a freeform VBR mode. It roughly centers on 350 kbps stereo */
+
+#ifndef _V_MODES_E_H_
+#define _V_MODES_E_H_
+
+#include <stdio.h>
+#include "vorbis/codec.h"
+#include "backends.h"
+
+#include "books/lsp12_0.vqh"
+#include "books/lsp30_0.vqh"
+
+#include "books/res0_350_128aux.vqh"
+#include "books/res0_350_1024aux.vqh"
+
+#include "books/res0_350_128_1.vqh"
+#include "books/res0_350_128_2.vqh"
+#include "books/res0_350_128_3.vqh"
+#include "books/res0_350_128_4.vqh"
+#include "books/res0_350_128_5.vqh"
+
+#include "books/res0_350_1024_1.vqh"
+#include "books/res0_350_1024_2.vqh"
+#include "books/res0_350_1024_3.vqh"
+#include "books/res0_350_1024_4.vqh"
+#include "books/res0_350_1024_5.vqh"
+
+static vorbis_info_psy _psy_set_E ={
+ 1,/*athp*/
+ 0,/*decayp*/
+ 1,/*smoothp*/
+
+ -140.f,
+ -180.f,
+
+ 16,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 0,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{0}},
+
+ 1,/* peakattp */
+ {{-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-30.f}, /*63*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-30.f}, /*88*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-30.f}, /*125*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-30.f}, /*175*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-30.f}, /*250*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-30.f}, /*350*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-28.f,-28.f,-30.f}, /*500*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-24.f,-28.f}, /*700*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-24.f,-28.f}, /*1000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-24.f,-28.f}, /*1400*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-24.f,-28.f}, /*2000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-24.f,-28.f}, /*2800*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-24.f,-28.f}, /*4000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-24.f,-28.f}, /*5600*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-24.f,-28.f}, /*8000*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-24.f,-28.f}, /*11500*/
+ {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-22.f,-24.f,-28.f}, /*16000*/
+ },
+
+ 0,/*noisemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ .5,
+ .5,
+ 25,
+ 25,
+ {0},
+
+ 110.f,
+
+ -0.f, -.004f /* attack/decay control */
+};
+
+/* with GNUisms, this could be short and readable. Oh well */
+static vorbis_info_time0 _time_set0_E={0};
+static vorbis_info_floor0 _floor_set0_E={12, 44100, 64, 12,150, 1, {0} };
+static vorbis_info_floor0 _floor_set1_E={30, 44100, 256, 12,150, 1, {1} };
+static vorbis_info_residue0 _residue_set0_E={0,128, 32,6,2,
+ {0,1,1,1,1,1},
+ {4,5,6,7,8},
+
+ {0,9999,9999,9999,9999},
+ {99.f,2.5f,6.5f,15.5f,29.5f},
+ {5,5,5,5,5},
+ {99,99,99,99,99}};
+
+static vorbis_info_residue0 _residue_set1_E={0,1024, 32,6,3,
+ {0,1,1,1,1,1},
+ {9,10,11,12,13},
+
+ {0,9999,9999,9999,9999},
+ {99.f,2.5f,6.5f,15.5f,29.5f},
+ {5,5,5,5,5},
+ {99,99,99,99,99}};
+
+static vorbis_info_mapping0 _mapping_set0_E={1, {0,0}, {0}, {0}, {0}, {0}};
+static vorbis_info_mapping0 _mapping_set1_E={1, {0,0}, {0}, {1}, {1}, {0}};
+static vorbis_info_mode _mode_set0_E={0,0,0,0};
+static vorbis_info_mode _mode_set1_E={1,0,0,1};
+
+/* CD quality stereo, no channel coupling */
+codec_setup_info info_E={
+
+ /* smallblock, largeblock */
+ {256, 2048},
+ /* modes,maps,times,floors,residues,books,psys */
+ 2, 2, 1, 2, 2, 14, 1,
+ /* modes */
+ {&_mode_set0_E,&_mode_set1_E},
+ /* maps */
+ {0,0},{&_mapping_set0_E,&_mapping_set1_E},
+ /* times */
+ {0,0},{&_time_set0_E},
+ /* floors */
+ {0,0},{&_floor_set0_E,&_floor_set1_E},
+ /* residue */
+ {0,0},{&_residue_set0_E,&_residue_set1_E},
+ /* books */
+ {&_vq_book_lsp12_0, /* 0 */
+ &_vq_book_lsp30_0, /* 1 */
+
+ &_huff_book_res0_350_128aux,
+ &_huff_book_res0_350_1024aux,
+
+ &_vq_book_res0_350_128_1,
+ &_vq_book_res0_350_128_2,
+ &_vq_book_res0_350_128_3,
+ &_vq_book_res0_350_128_4,
+ &_vq_book_res0_350_128_5,
+
+ &_vq_book_res0_350_1024_1,
+ &_vq_book_res0_350_1024_2,
+ &_vq_book_res0_350_1024_3,
+ &_vq_book_res0_350_1024_4,
+ &_vq_book_res0_350_1024_5,
+
+ },
+ /* psy */
+ {&_psy_set_E},
+ /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
+ 256, 24.f, 6.f, -96.f
+};
+
+#define PREDEF_INFO_MAX 0
+
+#endif
diff --git a/lib/psy.c b/lib/psy.c
new file mode 100644
index 00000000..dff9fb9c
--- /dev/null
+++ b/lib/psy.c
@@ -0,0 +1,654 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: psychoacoustics not including preecho
+ last mod: $Id: psy.c,v 1.34.2.1 2000/12/27 23:46:35 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include "vorbis/codec.h"
+
+#include "masking.h"
+#include "psy.h"
+#include "os.h"
+#include "lpc.h"
+#include "smallft.h"
+#include "scales.h"
+#include "misc.h"
+
+#define NEGINF -9999.f
+
+/* Why Bark scale for encoding but not masking computation? Because
+ masking has a strong harmonic dependancy */
+
+/* the beginnings of real psychoacoustic infrastructure. This is
+ still not tightly tuned */
+void _vi_psy_free(vorbis_info_psy *i){
+ if(i){
+ memset(i,0,sizeof(vorbis_info_psy));
+ _ogg_free(i);
+ }
+}
+
+vorbis_info_psy *_vi_psy_copy(vorbis_info_psy *i){
+ vorbis_info_psy *ret=_ogg_malloc(sizeof(vorbis_info_psy));
+ memcpy(ret,i,sizeof(vorbis_info_psy));
+ return(ret);
+}
+
+/* Set up decibel threshold slopes on a Bark frequency scale */
+/* ATH is the only bit left on a Bark scale. No reason to change it
+ right now */
+static void set_curve(float *ref,float *c,int n, float crate){
+ int i,j=0;
+
+ for(i=0;i<MAX_BARK-1;i++){
+ int endpos=rint(fromBARK(i+1)*2*n/crate);
+ float base=ref[i];
+ if(j<endpos){
+ float delta=(ref[i+1]-base)/(endpos-j);
+ for(;j<endpos && j<n;j++){
+ c[j]=base;
+ base+=delta;
+ }
+ }
+ }
+}
+
+static void min_curve(float *c,
+ float *c2){
+ int i;
+ for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i];
+}
+static void max_curve(float *c,
+ float *c2){
+ int i;
+ for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i];
+}
+
+static void attenuate_curve(float *c,float att){
+ int i;
+ for(i=0;i<EHMER_MAX;i++)
+ c[i]+=att;
+}
+
+static void interp_curve(float *c,float *c1,float *c2,float del){
+ int i;
+ for(i=0;i<EHMER_MAX;i++)
+ c[i]=c2[i]*del+c1[i]*(1.f-del);
+}
+
+static void setup_curve(float **c,
+ int band,
+ float *curveatt_dB){
+ int i,j;
+ float ath[EHMER_MAX];
+ float tempc[P_LEVELS][EHMER_MAX];
+
+ memcpy(c[0]+2,c[4]+2,sizeof(float)*EHMER_MAX);
+ memcpy(c[2]+2,c[4]+2,sizeof(float)*EHMER_MAX);
+
+ /* we add back in the ATH to avoid low level curves falling off to
+ -infinity and unneccessarily cutting off high level curves in the
+ curve limiting (last step). But again, remember... a half-band's
+ settings must be valid over the whole band, and it's better to
+ mask too little than too much, so be pessimal. */
+
+ for(i=0;i<EHMER_MAX;i++){
+ float oc_min=band*.5+(i-EHMER_OFFSET)*.125;
+ float oc_max=band*.5+(i-EHMER_OFFSET+1)*.125;
+ float bark=toBARK(fromOC(oc_min));
+ int ibark=floor(bark);
+ float del=bark-ibark;
+ float ath_min,ath_max;
+
+ if(ibark<26)
+ ath_min=ATH_Bark_dB[ibark]*(1.f-del)+ATH_Bark_dB[ibark+1]*del;
+ else
+ ath_min=ATH_Bark_dB[25];
+
+ bark=toBARK(fromOC(oc_max));
+ ibark=floor(bark);
+ del=bark-ibark;
+
+ if(ibark<26)
+ ath_max=ATH_Bark_dB[ibark]*(1.f-del)+ATH_Bark_dB[ibark+1]*del;
+ else
+ ath_max=ATH_Bark_dB[25];
+
+ ath[i]=min(ath_min,ath_max);
+ }
+
+ /* The c array is comes in as dB curves at 20 40 60 80 100 dB.
+ interpolate intermediate dB curves */
+ for(i=1;i<P_LEVELS;i+=2){
+ interp_curve(c[i]+2,c[i-1]+2,c[i+1]+2,.5);
+ }
+
+ /* normalize curves so the driving amplitude is 0dB */
+ /* make temp curves with the ATH overlayed */
+ for(i=0;i<P_LEVELS;i++){
+ attenuate_curve(c[i]+2,curveatt_dB[i]);
+ memcpy(tempc[i],ath,EHMER_MAX*sizeof(float));
+ attenuate_curve(tempc[i],-i*10.f);
+ max_curve(tempc[i],c[i]+2);
+ }
+
+ /* Now limit the louder curves.
+
+ the idea is this: We don't know what the playback attenuation
+ will be; 0dB SL moves every time the user twiddles the volume
+ knob. So that means we have to use a single 'most pessimal' curve
+ for all masking amplitudes, right? Wrong. The *loudest* sound
+ can be in (we assume) a range of ...+100dB] SL. However, sounds
+ 20dB down will be in a range ...+80], 40dB down is from ...+60],
+ etc... */
+
+ for(j=1;j<P_LEVELS;j++){
+ min_curve(tempc[j],tempc[j-1]);
+ min_curve(c[j]+2,tempc[j]);
+ }
+
+ /* add fenceposts */
+ for(j=0;j<P_LEVELS;j++){
+
+ for(i=0;i<EHMER_MAX;i++)
+ if(c[j][i+2]>-200.f){
+ c[j][0]=i;
+ break;
+ }
+
+ for(i=EHMER_MAX-1;i>=0;i--)
+ if(c[j][i+2]>-200.f){
+ c[j][1]=i;
+ break;
+ }
+
+ }
+}
+
+void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){
+ long i,j;
+ long maxoc;
+ memset(p,0,sizeof(vorbis_look_psy));
+
+
+ p->eighth_octave_lines=vi->eighth_octave_lines;
+ p->shiftoc=rint(log(vi->eighth_octave_lines*8)/log(2))-1;
+
+ p->firstoc=toOC(.25f*rate/n)*(1<<(p->shiftoc+1))-vi->eighth_octave_lines;
+ maxoc=toOC((n*.5f-.25f)*rate/n)*(1<<(p->shiftoc+1))+.5f;
+ p->total_octave_lines=maxoc-p->firstoc+1;
+
+ p->ath=_ogg_malloc(n*sizeof(float));
+ p->octave=_ogg_malloc(n*sizeof(int));
+ p->bark=_ogg_malloc(n*sizeof(float));
+ p->vi=vi;
+ p->n=n;
+
+ /* set up the lookups for a given blocksize and sample rate */
+ /* Vorbis max sample rate is currently limited by 26 Bark (54kHz) */
+ set_curve(ATH_Bark_dB, p->ath,n,rate);
+ for(i=0;i<n;i++)
+ p->bark[i]=toBARK(rate/(2*n)*i);
+
+ for(i=0;i<n;i++)
+ p->octave[i]=toOC((i*.5f+.25f)*rate/n)*(1<<(p->shiftoc+1))+.5f;
+
+ p->tonecurves=_ogg_malloc(P_BANDS*sizeof(float **));
+ p->noisemedian=_ogg_malloc(n*sizeof(float *));
+ p->peakatt=_ogg_malloc(P_BANDS*sizeof(float *));
+ for(i=0;i<P_BANDS;i++){
+ p->tonecurves[i]=_ogg_malloc(P_LEVELS*sizeof(float *));
+ p->peakatt[i]=_ogg_malloc(P_LEVELS*sizeof(float));
+ }
+
+ for(i=0;i<P_BANDS;i++)
+ for(j=0;j<P_LEVELS;j++){
+ p->tonecurves[i][j]=_ogg_malloc((EHMER_MAX+2)*sizeof(float));
+ }
+
+ /* OK, yeah, this was a silly way to do it */
+ memcpy(p->tonecurves[0][4]+2,tone_125_40dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[0][6]+2,tone_125_60dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[0][8]+2,tone_125_80dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[0][10]+2,tone_125_100dB_SL,sizeof(float)*EHMER_MAX);
+
+ memcpy(p->tonecurves[2][4]+2,tone_125_40dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[2][6]+2,tone_125_60dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[2][8]+2,tone_125_80dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[2][10]+2,tone_125_100dB_SL,sizeof(float)*EHMER_MAX);
+
+ memcpy(p->tonecurves[4][4]+2,tone_250_40dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[4][6]+2,tone_250_60dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[4][8]+2,tone_250_80dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[4][10]+2,tone_250_100dB_SL,sizeof(float)*EHMER_MAX);
+
+ memcpy(p->tonecurves[6][4]+2,tone_500_40dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[6][6]+2,tone_500_60dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[6][8]+2,tone_500_80dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[6][10]+2,tone_500_100dB_SL,sizeof(float)*EHMER_MAX);
+
+ memcpy(p->tonecurves[8][4]+2,tone_1000_40dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[8][6]+2,tone_1000_60dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[8][8]+2,tone_1000_80dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[8][10]+2,tone_1000_100dB_SL,sizeof(float)*EHMER_MAX);
+
+ memcpy(p->tonecurves[10][4]+2,tone_2000_40dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[10][6]+2,tone_2000_60dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[10][8]+2,tone_2000_80dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[10][10]+2,tone_2000_100dB_SL,sizeof(float)*EHMER_MAX);
+
+ memcpy(p->tonecurves[12][4]+2,tone_4000_40dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[12][6]+2,tone_4000_60dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[12][8]+2,tone_4000_80dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[12][10]+2,tone_4000_100dB_SL,sizeof(float)*EHMER_MAX);
+
+ memcpy(p->tonecurves[14][4]+2,tone_8000_40dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[14][6]+2,tone_8000_60dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[14][8]+2,tone_8000_80dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[14][10]+2,tone_8000_100dB_SL,sizeof(float)*EHMER_MAX);
+
+ memcpy(p->tonecurves[16][4]+2,tone_8000_40dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[16][6]+2,tone_8000_60dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[16][8]+2,tone_8000_80dB_SL,sizeof(float)*EHMER_MAX);
+ memcpy(p->tonecurves[16][10]+2,tone_8000_100dB_SL,sizeof(float)*EHMER_MAX);
+
+ /* interpolate curves between */
+ for(i=1;i<P_BANDS;i+=2)
+ for(j=4;j<P_LEVELS;j+=2){
+ memcpy(p->tonecurves[i][j]+2,p->tonecurves[i-1][j]+2,EHMER_MAX*sizeof(float));
+ /*interp_curve(p->tonecurves[i][j],
+ p->tonecurves[i-1][j],
+ p->tonecurves[i+1][j],.5);*/
+ min_curve(p->tonecurves[i][j]+2,p->tonecurves[i+1][j]+2);
+ }
+
+ /* set up the final curves */
+ for(i=0;i<P_BANDS;i++)
+ setup_curve(p->tonecurves[i],i,vi->toneatt[i]);
+
+ /* set up attenuation levels */
+ for(i=0;i<P_BANDS;i++)
+ for(j=0;j<P_LEVELS;j++){
+ p->peakatt[i][j]=p->vi->peakatt[i][j];
+ }
+
+ /* set up rolling noise median */
+ for(i=0;i<n;i++){
+ float halfoc=toOC((i+.5)*rate/(2.*n))*2.+2.;
+ int inthalfoc;
+ float del;
+
+ if(halfoc<0)halfoc=0;
+ if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
+ inthalfoc=(int)halfoc;
+ del=halfoc-inthalfoc;
+
+ p->noisemedian[i]=
+ p->vi->noisemedian[inthalfoc]*(1.-del) +
+ p->vi->noisemedian[inthalfoc+1]*del;
+ }
+ /*_analysis_output("mediancurve",0,p->noisemedian,n,0,0);*/
+}
+
+void _vp_psy_clear(vorbis_look_psy *p){
+ int i,j;
+ if(p){
+ if(p->ath)_ogg_free(p->ath);
+ if(p->octave)_ogg_free(p->octave);
+ if(p->bark)_ogg_free(p->bark);
+ if(p->tonecurves){
+ for(i=0;i<P_BANDS;i++){
+ for(j=0;j<P_LEVELS;j++){
+ _ogg_free(p->tonecurves[i][j]);
+ }
+ _ogg_free(p->tonecurves[i]);
+ _ogg_free(p->peakatt[i]);
+ }
+ _ogg_free(p->tonecurves);
+ _ogg_free(p->noisemedian);
+ _ogg_free(p->peakatt);
+ }
+ memset(p,0,sizeof(vorbis_look_psy));
+ }
+}
+
+/* octave/(8*eighth_octave_lines) x scale and dB y scale */
+static void seed_curve(float *seed,
+ float **curves,
+ float amp,
+ int oc,int n,int linesper,float dBoffset){
+ int i;
+ long seedptr;
+ float *posts,*curve;
+
+ int choice=(int)((amp+dBoffset)*.1f);
+ choice=max(choice,0);
+ choice=min(choice,8);
+ posts=curves[choice];
+ curve=posts+2;
+ seedptr=oc+(posts[0]-16)*linesper-(linesper>>1);
+
+ for(i=posts[0];i<posts[1];i++){
+ if(seedptr>0){
+ float lin=amp+curve[i];
+ if(seed[seedptr]<lin)seed[seedptr]=lin;
+ }
+ seedptr+=linesper;
+ if(seedptr>=n)break;
+ }
+}
+
+static void seed_peak(float *seed,
+ float *att,
+ float amp,
+ int oc,
+ int linesper,
+ float dBoffset){
+ long seedptr;
+
+ int choice=(int)((amp+dBoffset)*.1f);
+ choice=max(choice,0);
+ choice=min(choice,P_LEVELS-1);
+ seedptr=oc-(linesper>>1);
+
+ amp+=att[choice];
+ if(seed[seedptr]<amp)seed[seedptr]=amp;
+
+}
+
+static void seed_loop(vorbis_look_psy *p,
+ float ***curves,
+ float **att,
+ float *f,
+ float *flr,
+ float *seeds,
+ float specmax){
+ vorbis_info_psy *vi=p->vi;
+ long n=p->n,i;
+ float dBoffset=vi->max_curve_dB-specmax;
+
+ /* prime the working vector with peak values */
+
+ for(i=0;i<n;i++){
+ float max=f[i];
+ int oc=p->octave[i];
+ while(i+1<n && p->octave[i+1]==oc){
+ i++;
+ if(f[i]>max)max=f[i];
+ }
+
+ if(max>flr[i]){
+ oc=oc>>p->shiftoc;
+ if(oc>=P_BANDS)oc=P_BANDS-1;
+ if(oc<0)oc=0;
+ if(vi->tonemaskp)
+ seed_curve(seeds,
+ curves[oc],
+ max,
+ p->octave[i]-p->firstoc,
+ p->total_octave_lines,
+ p->eighth_octave_lines,
+ dBoffset);
+ if(vi->peakattp)
+ seed_peak(seeds,
+ att[oc],
+ max,
+ p->octave[i]-p->firstoc,
+ p->eighth_octave_lines,
+ dBoffset);
+ }
+ }
+}
+
+/* bleaugh, this is more complicated than it needs to be */
+static void max_seeds(vorbis_look_psy *p,float *seeds,float *flr){
+ long n=p->total_octave_lines,i;
+ int linesper=p->eighth_octave_lines;
+ long *posstack=alloca(n*sizeof(long));
+ float *ampstack=alloca(n*sizeof(float));
+ long stack=0;
+
+ for(i=0;i<n;i++){
+ if(stack<2){
+ posstack[stack]=i;
+ ampstack[stack++]=seeds[i];
+ }else{
+ while(1){
+ if(seeds[i]<ampstack[stack-1]){
+ posstack[stack]=i;
+ ampstack[stack++]=seeds[i];
+ break;
+ }else{
+ if(i<posstack[stack-1]+linesper){
+ if(stack>1 && ampstack[stack-1]<=ampstack[stack-2] &&
+ i<posstack[stack-2]+linesper){
+ /* we completely overlap, making stack-1 irrelevant. pop it */
+ stack--;
+ continue;
+ }
+ }
+ posstack[stack]=i;
+ ampstack[stack++]=seeds[i];
+ break;
+
+ }
+ }
+ }
+ }
+
+ /* the stack now contains only the positions that are relevant. Scan
+ 'em straight through */
+ {
+ long pos=0;
+ long linpos=0;
+ for(i=0;i<stack;i++){
+ long endpos;
+ if(i<stack-1 && ampstack[i+1]>ampstack[i]){
+ endpos=posstack[i+1];
+ }else{
+ endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is
+ discarded in short frames */
+ }
+ if(endpos>n)endpos=n;
+ for(;pos<endpos;pos++)
+ seeds[pos]=ampstack[i];
+ }
+
+ pos=0;
+ while(linpos+1<p->n){
+ float min=seeds[pos];
+ long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc;
+ while(pos+1<=end){
+ pos++;
+ if((seeds[pos]>NEGINF && seeds[pos]<min) || min==NEGINF)min=seeds[pos];
+ }
+
+ /* seed scale is log. Floor is linear. Map back to it */
+ end=pos+p->firstoc;
+ for(;linpos<p->n && p->octave[linpos]<=end;linpos++)
+ if(flr[linpos]<min)flr[linpos]=min;
+ }
+ {
+ float v=seeds[p->total_octave_lines-1];
+ for(;linpos<p->n;linpos++)
+ if(flr[linpos]<v)flr[linpos]=v;
+ }
+ }
+
+ /* there. Linear time. I now remember this was on a problem set I
+ had in Grad Skool... I didn't solve it at the time ;-) */
+}
+
+#define BIN(x) ((int)((x)*-4.))
+#define BINdB(x) ((x)*-.25)
+static void bark_noise_median(long n,float *b,float *f,float *noise,
+ float lowidth,float hiwidth,
+ int lomin,int himin,
+ float *thresh){
+ long i=0,lo=0,hi=0;
+ long *radix=alloca(200*4*sizeof(long)); /* quarter-dB bins */
+
+ long countabove=0;
+ long median=200*4-1;
+ long countbelow=0;
+
+ memset(radix,0,200*4*sizeof(long));
+
+ for(i=0;i<n;i++){
+ /* find new lo/hi */
+ for(;hi<n && (b[hi]<=b[i]+hiwidth || hi<i+himin);hi++){
+ int bin=BIN(f[hi]);
+ if(bin>=200*4)bin=200*4-1;
+ radix[bin]++;
+ if(bin<median)
+ countabove++;
+ else
+ countbelow++;
+ }
+ for(;lo<i && b[lo]+lowidth<=b[i] && lo+lomin<i;lo++){
+ int bin=BIN(f[lo]);
+ if(bin>=200*4)bin=200*4-1;
+ radix[bin]--;
+ if(bin<median)
+ countabove--;
+ else
+ countbelow--;
+ }
+
+ /* move the median if needed */
+ if(countabove+countbelow){
+
+ while(thresh[i]>countbelow/(float)(countabove+countbelow) && median>0){
+ median--;
+ countabove-=radix[median];
+ countbelow+=radix[median];
+ }
+
+ while(thresh[i]<(countbelow-radix[median])/
+ (float)(countabove+countbelow) && median+1<200*4){
+ countabove+=radix[median];
+ countbelow-=radix[median];
+ median++;
+ }
+ }
+
+ noise[i]=BINdB(median);
+ }
+
+}
+
+void _vp_compute_mask(vorbis_look_psy *p,
+ float *fft,
+ float *mdct,
+ float *flr,
+ float *decay){
+ int i,n=p->n;
+ float specmax=NEGINF;
+ static int seq=0;
+
+ float *seed=alloca(sizeof(float)*p->total_octave_lines);
+ for(i=0;i<p->total_octave_lines;i++)seed[i]=NEGINF;
+
+ /* go to dB scale. Also find the highest peak so we know the limits */
+ for(i=0;i<n;i++){
+ fft[i]=todB(fft[i]);
+ if(fft[i]>specmax)specmax=fft[i];
+ }
+ for(i=0;i<n;i++){
+ mdct[i]=todB(mdct[i]);
+ }
+
+ _analysis_output("mdct",seq,mdct,n,0,0);
+ _analysis_output("fft",seq,fft,n,0,0);
+
+ /* noise masking */
+ if(p->vi->noisemaskp){
+ bark_noise_median(n,p->bark,mdct,flr,
+ p->vi->noisewindowlo,
+ p->vi->noisewindowhi,
+ p->vi->noisewindowlomin,
+ p->vi->noisewindowhimin,
+ p->noisemedian);
+ /* suppress any noise curve > specmax+p->vi->noisemaxsupp */
+ for(i=0;i<n;i++)
+ if(flr[i]>specmax+p->vi->noisemaxsupp)
+ flr[i]=specmax+p->vi->noisemaxsupp;
+ _analysis_output("noise",seq,flr,n,0,0);
+ }else{
+ for(i=0;i<n;i++)flr[i]=NEGINF;
+ }
+
+ /* set the ATH (floating below specmax by a specified att) */
+ if(p->vi->athp){
+ float att=specmax+p->vi->ath_adjatt;
+ if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
+
+ for(i=0;i<n;i++){
+ float av=p->ath[i]+att;
+ if(av>flr[i])flr[i]=av;
+ }
+ }
+
+ _analysis_output("ath",seq,flr,n,0,0);
+
+ /* tone/peak masking */
+
+ /* XXX apply decay to the fft here */
+
+ seed_loop(p,p->tonecurves,p->peakatt,fft,flr,seed,specmax);
+ _analysis_output("seed",seq,seed,p->total_octave_lines,0,0);
+ max_seeds(p,seed,flr);
+
+ /* treat the near-DC offset bin[s] special care */
+ {
+ float v=mdct[0]+p->vi->nearDCdB;
+ for(i=0;i<p->vi->nearDCp;i++)
+ if(flr[i]>v)flr[i]=v;
+ }
+
+ _analysis_output("final",seq,flr,n,0,0);
+
+ /* doing this here is clean, but we need to find a faster way to do
+ it than to just tack it on */
+
+ for(i=0;i<n;i++)if(mdct[i]>=flr[i])break;
+ if(i==n)for(i=0;i<n;i++)flr[i]=NEGINF;
+
+ seq++;
+}
+
+
+/* this applies the floor and (optionally) tries to preserve noise
+ energy in low resolution portions of the spectrum */
+/* f and flr are *linear* scale, not dB */
+void _vp_apply_floor(vorbis_look_psy *p,float *f, float *flr){
+ float *work=alloca(p->n*sizeof(float));
+ int j;
+
+ /* subtract the floor */
+ for(j=0;j<p->n;j++){
+ if(flr[j]<=0)
+ work[j]=0.f;
+ else
+ work[j]=f[j]/flr[j];
+ }
+
+ memcpy(f,work,p->n*sizeof(float));
+}
+
+
diff --git a/lib/psy.h b/lib/psy.h
new file mode 100644
index 00000000..e94ba596
--- /dev/null
+++ b/lib/psy.h
@@ -0,0 +1,103 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: random psychoacoustics (not including preecho)
+ last mod: $Id: psy.h,v 1.16.2.1 2000/12/27 23:46:35 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_PSY_H_
+#define _V_PSY_H_
+#include "smallft.h"
+
+#ifndef EHMER_MAX
+#define EHMER_MAX 56
+#endif
+
+/* psychoacoustic setup ********************************************/
+#define MAX_BARK 27
+#define P_BANDS 17
+#define P_LEVELS 11
+typedef struct vorbis_info_psy{
+ int athp;
+ int decayp;
+
+ float ath_adjatt;
+ float ath_maxatt;
+
+ int eighth_octave_lines;
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ int nearDCp;
+ float nearDCdB;
+
+ int tonemaskp;
+ float toneatt[P_BANDS][P_LEVELS];
+
+ int peakattp;
+ float peakatt[P_BANDS][P_LEVELS];
+
+ int noisemaskp;
+ float noisemaxsupp;
+ float noisewindowlo;
+ float noisewindowhi;
+ int noisewindowlomin;
+ int noisewindowhimin;
+ float noisemedian[P_BANDS];
+
+ float max_curve_dB;
+
+ /* decay setup */
+ float attack_coeff;
+ float decay_coeff;
+} vorbis_info_psy;
+
+typedef struct {
+ int n;
+ struct vorbis_info_psy *vi;
+
+ float ***tonecurves;
+ float **peakatt;
+ float *noisemedian;
+
+ float *ath;
+ long *octave; /* in n.ocshift format */
+ float *bark;
+
+ long firstoc;
+ long shiftoc;
+ int eighth_octave_lines; /* power of two, please */
+ int total_octave_lines;
+
+} vorbis_look_psy;
+
+extern void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate);
+extern void _vp_psy_clear(vorbis_look_psy *p);
+extern void *_vi_psy_dup(void *source);
+
+extern void _vi_psy_free(vorbis_info_psy *i);
+extern vorbis_info_psy *_vi_psy_copy(vorbis_info_psy *i);
+
+extern void _vp_compute_mask(vorbis_look_psy *p,
+ float *fft,
+ float *mdct,
+ float *floor,
+ float *decay);
+extern void _vp_apply_floor(vorbis_look_psy *p,float *f,float *flr);
+
+#endif
+
+
diff --git a/lib/psytune.c b/lib/psytune.c
new file mode 100644
index 00000000..7ae9e8f8
--- /dev/null
+++ b/lib/psytune.c
@@ -0,0 +1,392 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: simple utility that runs audio through the psychoacoustics
+ without encoding
+ last mod: $Id: psytune.c,v 1.11.2.1 2000/12/27 23:46:35 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "vorbis/codec.h"
+#include "os.h"
+#include "psy.h"
+#include "mdct.h"
+#include "smallft.h"
+#include "window.h"
+#include "scales.h"
+#include "lpc.h"
+#include "lsp.h"
+
+static vorbis_info_psy _psy_set0={
+ 1,/*athp*/
+ 0,/*decayp*/
+
+ -100.f,
+ -140.f,
+
+ 8,
+
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */
+ /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
+ /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
+
+ 2,
+ -40.f, /* nearDCdB */
+
+ 1,/* tonemaskp */
+ /* 0 10 20 30 40 50 60 70 80 90 100 */
+ {{-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*63*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*88*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*125*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*175*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*250*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*350*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*500*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*700*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*1000*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*1400*/
+ {-40.,-40.,-40.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*2000*/
+ {-40.,-40.,-40.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*2800*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*4000*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*5600*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*8000*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*11500*/
+ {-30.,-35.,-35.,-40.,-40.,-50.,-60.,-70.,-80.,-90.,-100.}, /*16000*/
+ },
+
+ 0,/* peakattp */
+ {{-14.,-16.,-18.,-19.,-20.,-21.,-22.,-22.,-28.,-28.,-28.}, /*63*/
+ {-14.,-16.,-18.,-19.,-20.,-21.,-22.,-22.,-28.,-28.,-28.}, /*88*/
+ {-14.,-16.,-18.,-19.,-20.,-21.,-22.,-22.,-28.,-28.,-28.}, /*125*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-18.,-28.,-28.,-28.}, /*175*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-18.,-28.,-28.,-28.}, /*250*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-18.,-28.,-28.,-28.}, /*350*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-28.,-28.,-28.,-28.}, /*500*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-28.}, /*700*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-28.}, /*1000*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-28.}, /*1400*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-28.}, /*2000*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-28.}, /*2400*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-28.}, /*4000*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-18.,-20.}, /*5600*/
+ { -7., -8., -9.,-10.,-10.,-11.,-12.,-13.,-15.,-16.,-17.}, /*8000*/
+ { -6., -7., -9., -9., -9., -9.,-10.,-11.,-12.,-13.,-14.}, /*11500*/
+ { -6., -6., -9., -9., -9., -9., -9., -9.,-10.,-11.,-12.}, /*16000*/
+ },
+
+
+ 1,/*noisemaskp */
+ -40.f, /* suppress any noise curve over maxspec+n */
+ .5f, /* low window */
+ .5f, /* high window */
+ 25,
+ 25,
+ {.000f, /*63*/
+ .000f, /*88*/
+ .000f, /*125*/
+ .000f, /*175*/
+ .000f, /*250*/
+ .000f, /*350*/
+ .000f, /*500*/
+ .500f, /*700*/
+ .500f, /*1000*/
+ .500f, /*1400*/
+ .500f, /*2000*/
+ .500f, /*2800*/
+ .700f, /*4000*/
+ .800f, /*5600*/
+ .850f, /*8000*/
+ .850f, /*11500*/
+ .900f, /*16000*/
+ },
+
+ 105.f, /* even decade + 5 is important; saves an rint() later in a
+ tight loop) */
+
+ -0.f, -.004f /* attack/decay control */
+};
+
+static int noisy=0;
+void analysis(char *base,int i,float *v,int n,int bark,int dB){
+ if(noisy){
+ int j;
+ FILE *of;
+ char buffer[80];
+ sprintf(buffer,"%s_%d.m",base,i);
+ of=fopen(buffer,"w");
+
+ for(j=0;j<n;j++){
+ if(dB && v[j]==0)
+ fprintf(of,"\n\n");
+ else{
+ if(bark)
+ fprintf(of,"%g ",toBARK(22050.f*j/n));
+ else
+ fprintf(of,"%g ",(float)j);
+
+ if(dB){
+ fprintf(of,"%g\n",todB(fabs(v[j])));
+ }else{
+ fprintf(of,"%g\n",v[j]);
+ }
+ }
+ }
+ fclose(of);
+ }
+}
+
+typedef struct {
+ long n;
+ int ln;
+ int m;
+ int *linearmap;
+
+ lpc_lookup lpclook;
+} vorbis_look_floor0;
+
+long frameno=0;
+
+/* hacked from floor0.c */
+static void floorinit(vorbis_look_floor0 *look,int n,int m,int ln){
+ int j;
+ float scale;
+ look->m=m;
+ look->n=n;
+ look->ln=ln;
+ lpc_init(&look->lpclook,look->ln,look->m);
+
+ scale=look->ln/toBARK(22050.f);
+
+ look->linearmap=_ogg_malloc(look->n*sizeof(int));
+ for(j=0;j<look->n;j++){
+ int val=floor( toBARK(22050.f/n*j) *scale);
+ if(val>look->ln)val=look->ln;
+ look->linearmap[j]=val;
+ }
+}
+
+int main(int argc,char *argv[]){
+ int eos=0;
+ float nonz=0.f;
+ float acc=0.f;
+ float tot=0.f;
+
+ int framesize=2048;
+ int order=32;
+ int map=256;
+
+ float *pcm[2],*out[2],*window,*lpc,*flr,*mask;
+ signed char *buffer,*buffer2;
+ mdct_lookup m_look;
+ drft_lookup f_look;
+ vorbis_look_psy p_look;
+ long i,j,k;
+
+ vorbis_look_floor0 floorlook;
+
+ int ath=0;
+ int decayp=0;
+
+ argv++;
+ while(*argv){
+ if(*argv[0]=='-'){
+ /* option */
+ if(argv[0][1]=='v'){
+ noisy=0;
+ }
+ if(argv[0][1]=='A'){
+ ath=0;
+ }
+ if(argv[0][1]=='D'){
+ decayp=0;
+ }
+ if(argv[0][1]=='X'){
+ ath=0;
+ decayp=0;
+ }
+ }else
+ if(*argv[0]=='+'){
+ /* option */
+ if(argv[0][1]=='v'){
+ noisy=1;
+ }
+ if(argv[0][1]=='A'){
+ ath=1;
+ }
+ if(argv[0][1]=='D'){
+ decayp=1;
+ }
+ if(argv[0][1]=='X'){
+ ath=1;
+ decayp=1;
+ }
+ }else
+ framesize=atoi(argv[0]);
+ argv++;
+ }
+
+ mask=_ogg_malloc(framesize*sizeof(float));
+ pcm[0]=_ogg_malloc(framesize*sizeof(float));
+ pcm[1]=_ogg_malloc(framesize*sizeof(float));
+ out[0]=_ogg_calloc(framesize/2,sizeof(float));
+ out[1]=_ogg_calloc(framesize/2,sizeof(float));
+ flr=_ogg_malloc(framesize*sizeof(float));
+ lpc=_ogg_malloc(order*sizeof(float));
+ buffer=_ogg_malloc(framesize*4);
+ buffer2=buffer+framesize*2;
+ window=_vorbis_window(0,framesize,framesize/2,framesize/2);
+ mdct_init(&m_look,framesize);
+ drft_init(&f_look,framesize);
+ _vp_psy_init(&p_look,&_psy_set0,framesize/2,44100);
+ floorinit(&floorlook,framesize/2,order,map);
+
+ for(i=0;i<P_BANDS;i++)
+ for(j=0;j<P_LEVELS;j++)
+ analysis("Ptonecurve",i*100+j,p_look.tonecurves[i][j],EHMER_MAX,0,0);
+
+ /* we cheat on the WAV header; we just bypass 44 bytes and never
+ verify that it matches 16bit/stereo/44.1kHz. */
+
+ fread(buffer,1,44,stdin);
+ fwrite(buffer,1,44,stdout);
+ memset(buffer,0,framesize*2);
+
+ analysis("window",0,window,framesize,0,0);
+
+ fprintf(stderr,"Processing for frame size %d...\n",framesize);
+
+ while(!eos){
+ long bytes=fread(buffer2,1,framesize*2,stdin);
+ if(bytes<framesize*2)
+ memset(buffer2+bytes,0,framesize*2-bytes);
+
+ if(bytes!=0){
+
+ /* uninterleave samples */
+ for(i=0;i<framesize;i++){
+ pcm[0][i]=((buffer[i*4+1]<<8)|
+ (0x00ff&(int)buffer[i*4]))/32768.f;
+ pcm[1][i]=((buffer[i*4+3]<<8)|
+ (0x00ff&(int)buffer[i*4+2]))/32768.f;
+ }
+
+ for(i=0;i<2;i++){
+ float amp;
+
+ analysis("pre",frameno,pcm[i],framesize,0,0);
+ memcpy(mask,pcm[i],sizeof(float)*framesize);
+
+ /* do the psychacoustics */
+ for(j=0;j<framesize;j++)
+ mask[j]=pcm[i][j]*=window[j];
+
+ drft_forward(&f_look,mask);
+
+ mask[0]/=(framesize/4.);
+ for(j=1;j<framesize-1;j+=2)
+ mask[(j+1)>>1]=4*hypot(mask[j],mask[j+1])/framesize;
+
+ mdct_forward(&m_look,pcm[i],pcm[i]);
+ memcpy(mask+framesize/2,pcm[i],sizeof(float)*framesize/2);
+ analysis("mdct",frameno,pcm[i],framesize/2,0,1);
+ analysis("fft",frameno,mask,framesize/2,0,1);
+
+ _vp_compute_mask(&p_look,mask,mask+framesize/2,flr,NULL);
+
+ analysis("floor",frameno,flr,framesize/2,0,0);
+
+ for(j=0;j<framesize/2;j++)
+ flr[j]=fromdB(flr[j]);
+
+
+ /*for(j=0;j<framesize/2;){
+ float energy=0.;
+ float acc=0.;
+ float *v=pcm[i]+j;
+ int flag=0;
+ for(k=0;k<32;k++){
+ energy+=v[k]*v[k];
+ if(fabs(v[k]/flr[j+k])>.5)acc+=v[k]*v[k];
+ }
+ if(acc*2<energy){
+ if(acc>0.)fprintf(stderr,"culling\n");
+ for(k=0;k<32;k++)v[k]=0;
+ }
+ j+=k;
+ }*/
+
+ _vp_apply_floor(&p_look,pcm[i],flr);
+
+
+ analysis("quant",frameno,pcm[i],framesize/2,0,0);
+
+ /* re-add floor */
+ for(j=0;j<framesize/2;j++){
+ float val=rint(pcm[i][j]);
+ tot++;
+ if(val){
+ nonz++;
+ acc+=log(fabs(val)*2.f+1.f)/log(2);
+ pcm[i][j]=val*flr[j];
+ }else{
+ pcm[i][j]=0.f;
+ }
+ }
+
+ analysis("final",frameno,pcm[i],framesize/2,0,1);
+
+ /* take it back to time */
+ mdct_backward(&m_look,pcm[i],pcm[i]);
+ for(j=0;j<framesize/2;j++)
+ out[i][j]+=pcm[i][j]*window[j];
+
+ frameno++;
+ }
+
+ /* write data. Use the part of buffer we're about to shift out */
+ for(i=0;i<2;i++){
+ char *ptr=buffer+i*2;
+ float *mono=out[i];
+ for(j=0;j<framesize/2;j++){
+ int val=mono[j]*32767.;
+ /* might as well guard against clipping */
+ if(val>32767)val=32767;
+ if(val<-32768)val=-32768;
+ ptr[0]=val&0xff;
+ ptr[1]=(val>>8)&0xff;
+ ptr+=4;
+ }
+ }
+
+ fprintf(stderr,"*");
+ fwrite(buffer,1,framesize*2,stdout);
+ memmove(buffer,buffer2,framesize*2);
+
+ for(i=0;i<2;i++){
+ for(j=0,k=framesize/2;j<framesize/2;j++,k++)
+ out[i][j]=pcm[i][k]*window[k];
+ }
+ }else
+ eos=1;
+ }
+ fprintf(stderr,"average raw bits of entropy: %.03g/sample\n",acc/tot);
+ fprintf(stderr,"average nonzero samples: %.03g/%d\n",nonz/tot*framesize/2,
+ framesize/2);
+ fprintf(stderr,"Done\n\n");
+ return 0;
+}
diff --git a/lib/scales.h b/lib/scales.h
new file mode 100644
index 00000000..4d80b455
--- /dev/null
+++ b/lib/scales.h
@@ -0,0 +1,51 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
+ * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: linear scale -> dB, Bark and Mel scales
+ last mod: $Id: scales.h,v 1.9.2.1 2000/12/27 23:46:36 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_SCALE_H_
+#define _V_SCALES_H_
+
+#include <math.h>
+
+/* 20log10(x) */
+#define DYNAMIC_RANGE_dB 200.f
+#define todB(x) ((x)==0?-400.f:log((x)*(x))*4.34294480f)
+#define todB_nn(x) ((x)==0.f?-400.f:log(x)*8.6858896f)
+#define fromdB(x) (exp((x)*.11512925f))
+
+/* The bark scale equations are approximations, since the original
+ table was somewhat hand rolled. The below are chosen to have the
+ best possible fit to the rolled tables, thus their somewhat odd
+ appearance (these are more accurate and over a longer range than
+ the oft-quoted bark equations found in the texts I have). The
+ approximations are valid from 0 - 30kHz (nyquist) or so.
+
+ all f in Hz, z in Bark */
+
+#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
+#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f)
+#define toMEL(n) (log(1.f+(n)*.001f)*1442.695f)
+#define fromMEL(m) (1000.f*exp((m)/1442.695f)-1000.f)
+
+/* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave
+ 0.0 */
+
+#define toOC(n) (log(n)*1.442695f-5.965784f)
+#define fromOC(o) (exp(((o)+5.965784f)*.693147f))
+
+#endif
+
diff --git a/libvorbis.spec b/libvorbis.spec
new file mode 100644
index 00000000..c6c0b09b
--- /dev/null
+++ b/libvorbis.spec
@@ -0,0 +1,84 @@
+%define name libvorbis
+%define version 1.0prebeta4
+%define release 1
+
+Summary: The Vorbis General Audio Compression Codec
+Name: %{name}
+Version: %{version}
+Release: %{release}
+Group: Libraries/Multimedia
+Copyright: LGPL
+URL: http://www.xiph.org/
+Vendor: Xiphophorus <team@xiph.org>
+Source: ftp://ftp.xiph.org/pub/ogg/vorbis/%{name}-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-root
+Requires: libogg >= 1.0beta3
+
+%description
+Ogg Vorbis is a fully open, non-proprietary, patent-and-royalty-free,
+general-purpose compressed audio format for audio and music at fixed
+and variable bitrates from 16 to 128 kbps/channel.
+
+%package devel
+Summary: Vorbis Library Development
+Group: Development/Libraries
+Requires: libogg-devel >= 1.0beta3
+Requires: libvorbis-devel = %{version}
+
+%description devel
+The libvorbis-devel package contains the header files and documentation
+needed to develop applications with libvorbis.
+
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+if [ ! -f configure ]; then
+ CFLAGS="$RPM_FLAGS" ./autogen.sh --prefix=/usr
+else
+ CFLAGS="$RPM_FLAGS" ./configure --prefix=/usr
+fi
+make
+
+%install
+[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT install
+
+%files
+%defattr(-,root,root)
+%doc COPYING
+%doc AUTHORS
+%doc README
+/usr/lib/libvorbis.so.*
+/usr/lib/libvorbisfile.so.*
+/usr/lib/libvorbisenc.so.*
+
+%files devel
+%doc doc/*.html
+%doc doc/*.png
+%doc doc/*.txt
+%doc doc/vorbisfile
+%doc doc/vorbisenc
+/usr/share/aclocal/vorbis.m4
+/usr/include/vorbis/codec.h
+/usr/include/vorbis/vorbisfile.h
+/usr/include/vorbis/vorbisenc.h
+/usr/lib/libvorbis.a
+/usr/lib/libvorbis.so
+/usr/lib/libvorbisfile.a
+/usr/lib/libvorbisfile.so
+/usr/lib/libvorbisenc.a
+/usr/lib/libvorbisenc.so
+
+%clean
+[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
+
+%changelog
+* Sat Oct 21 2000 Jack Moffitt <jack@icecast.org>
+- initial spec file created