The lib and vq, at least, build again. Tackling the examples and xmms
authorMonty <xiphmont@xiph.org>
Fri, 28 Jan 2000 09:05:21 +0000 (09:05 +0000)
committerMonty <xiphmont@xiph.org>
Fri, 28 Jan 2000 09:05:21 +0000 (09:05 +0000)
now.  There are still unfinished portions of the lib rearranging
(notably, floor0.c and res0.c)

Monty

svn path=/trunk/vorbis/; revision=244

25 files changed:
examples/Makefile.in
examples/encoder_example.c
include/vorbis/backends.h
include/vorbis/book/lsp20_0.vqh
include/vorbis/book/lsp32_0.vqh
include/vorbis/codebook.h
include/vorbis/codec.h
include/vorbis/vorbisfile.h
lib/Makefile.in
lib/block.c
lib/bookinternal.h
lib/codebook.c
lib/floor0.c
lib/info.c
lib/lpc.c
lib/lpc.h
lib/mapping0.c
lib/psy.c
lib/psy.h
lib/res0.c
lib/spectrum.c [deleted file]
lib/vorbisfile.c
vq/bookutil.c
vq/metrics.c
vq/vqsplit.c

index 1afcaae..b80ab68 100644 (file)
@@ -1,6 +1,6 @@
 # vorbis makefile configured for use with gcc on any platform
 
-# $Id: Makefile.in,v 1.3 2000/01/22 13:28:07 xiphmont Exp $
+# $Id: Makefile.in,v 1.4 2000/01/28 09:04:57 xiphmont Exp $
 
 ###############################################################################
 #                                                                             #
@@ -28,7 +28,7 @@ RANLIB=@RANLIB@
 LIBS=@LIBS@ -lm
 
 HFILES =       ../include/vorbis/codec.h ../include/vorbis/vorbisfile.h \
-               ../include/vorbis/internal.h ../include/vorbis/backend.h \
+               ../include/vorbis/internal.h ../include/vorbis/backends.h \
                ../include/vorbis/codebook.h
 OFILES =       encoder_example.o decoder_example.o chaining_example.o
 BINFILES =      encoder_example decoder_example chaining_example
index d8c37d4..85796b4 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: simple example encoder
- last mod: $Id: encoder_example.c,v 1.4 2000/01/22 13:28:09 xiphmont Exp $
+ last mod: $Id: encoder_example.c,v 1.5 2000/01/28 09:04:58 xiphmont Exp $
 
  ********************************************************************/
 
@@ -38,6 +38,8 @@ int main(){
   
   vorbis_info      vi; /* struct that stores all the static vorbis bitstream
                          settings */
+  vorbis_comment   vc; /* struct that stores all the user comments */
+                         settings */
   vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
   vorbis_block     vb; /* local working space for packet->PCM decode */
 
index 3728407..7c4f398 100644 (file)
@@ -13,7 +13,7 @@
 
  function: libvorbis backend and mapping structures; needed for 
            static mode headers
- last mod: $Id: backends.h,v 1.2 2000/01/22 13:28:10 xiphmont Exp $
+ last mod: $Id: backends.h,v 1.3 2000/01/28 09:04:59 xiphmont Exp $
 
  ********************************************************************/
 
@@ -59,7 +59,7 @@ typedef struct{
   int  (*forward)   (struct vorbis_block *,vorbis_look_floor *,
                     double *,double *);
   int  (*inverse)   (struct vorbis_block *,vorbis_look_floor *,
-                    double *,double *);
+                    double *);
 } vorbis_func_floor;
 
 typedef struct{
@@ -79,9 +79,9 @@ typedef struct{
   void (*free_info)    (vorbis_info_residue *);
   void (*free_look)    (vorbis_look_residue *);
   int  (*forward)      (struct vorbis_block *,vorbis_look_residue *,
-                       double *,double *);
+                       double **,int **,int);
   int  (*inverse)      (struct vorbis_block *,vorbis_look_residue *,
-                       double *,double *);
+                       double **,int);
 } vorbis_func_residue;
 
 typedef struct vorbis_info_residue0{
@@ -96,7 +96,8 @@ typedef struct vorbis_info_residue0{
 
 /* Mapping backend generic *****************************************/
 typedef struct{
-  void                 (*pack)  (vorbis_info_mapping *,oggpack_buffer *);
+  void                 (*pack)  (vorbis_info *,vorbis_info_mapping *,
+                                oggpack_buffer *);
   vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *);
   vorbis_look_mapping *(*look)  (vorbis_info *,vorbis_info_mode *,
                                 vorbis_info_mapping *);
index 383719b..6e94bf0 100644 (file)
@@ -1165,7 +1165,7 @@ static encode_aux _vq_aux_lsp20_0 = {
        1694, 1694
 };
 
-static codebook _vq_book_lsp20_0 = {
+static static_codebook _vq_book_lsp20_0 = {
        4, 256, 4152003, 2812515, 8, 1,
        _vq_quantlist_lsp20_0,
        _vq_lengthlist_lsp20_0,
index 3bf6dd3..01f3482 100644 (file)
@@ -1689,7 +1689,7 @@ static encode_aux _vq_aux_lsp32_0 = {
        2743, 2743
 };
 
-static codebook _vq_book_lsp32_0 = {
+static static_codebook _vq_book_lsp32_0 = {
        4, 256, 4089638, 2558033, 8, 1,
        _vq_quantlist_lsp32_0,
        _vq_lengthlist_lsp32_0,
index e4bbfed..d9680fb 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: codebook types
- last mod: $Id: codebook.h,v 1.3 2000/01/22 10:40:36 xiphmont Exp $
+ last mod: $Id: codebook.h,v 1.4 2000/01/28 09:05:00 xiphmont Exp $
 
  ********************************************************************/
 
@@ -69,7 +69,7 @@ typedef struct decode_aux{
 typedef struct codebook{
   long dim;           /* codebook dimensions (elements per vector) */
   long entries;       /* codebook entries */
-  static_codebook *c;
+  const static_codebook *c;
 
   double *valuelist;  /* list of dim*entries actual entry values */
   long   *codelist;   /* list of bitstream codewords for each entry */
index bc0fe7b..599e22d 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: libvorbis codec headers
- last mod: $Id: codec.h,v 1.5 2000/01/22 13:28:11 xiphmont Exp $
+ last mod: $Id: codec.h,v 1.6 2000/01/28 09:05:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -294,14 +294,14 @@ typedef struct vorbis_block{
 
 /* the comments are not part of vorbis_info so that vorbis_info can be
    static storage */
-typedef struct vorbis_comments{
+typedef struct vorbis_comment{
   /* unlimited user comment fields.  libvorbis writes 'libvorbis'
      whatever vendor is set to in encode */
   char **user_comments;
   int    comments;
   char  *vendor;
 
-} vorbis_comments;
+} vorbis_comment;
 
 
 /* libvorbis encodes in two abstraction layers; first we perform DSP
@@ -353,18 +353,21 @@ extern int      ogg_page_pageno(ogg_page *og);
 
 /* Vorbis PRIMITIVES: general ***************************************/
 
-extern int      vorbis_info_init(vorbis_info *vi,vorbis_comments *vc);
-extern int      vorbis_comment_init(vorbis_comments *vc);
-extern int      vorbis_comment_add(vorbis_comments *vc, char *comment); 
-extern int      vorbis_comment_clear(vorbis_comments *vc);
+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_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);
@@ -374,7 +377,7 @@ 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_comments *vc,
+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);
index 854e507..dda73ef 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.h,v 1.1 2000/01/05 03:10:47 xiphmont Exp $
+ last mod: $Id: vorbisfile.h,v 1.2 2000/01/28 09:05:02 xiphmont Exp $
 
  ********************************************************************/
 
@@ -37,6 +37,7 @@ typedef struct {
   long             *serialnos;
   int64_t           *pcmlengths;
   vorbis_info      *vi;
+  vorbis_comment  *vc;
 
   /* Decoding working state local storage */
   int64_t          pcm_offset;
@@ -72,6 +73,7 @@ extern int64_t ov_pcm_tell(OggVorbis_File *vf);
 extern double ov_time_tell(OggVorbis_File *vf);
 
 extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
+extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
 
 extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
                    int bigendianp,int word,int sgned,int *bitstream);
index eac125d..af28f6a 100644 (file)
@@ -1,6 +1,6 @@
 # vorbis makefile configured for use with gcc on any platform
 
-# $Id: Makefile.in,v 1.23 2000/01/22 13:28:13 xiphmont Exp $
+# $Id: Makefile.in,v 1.24 2000/01/28 09:05:05 xiphmont Exp $
 
 ###############################################################################
 #                                                                             #
@@ -28,14 +28,14 @@ RANLIB=@RANLIB@
 LIBS=@LIBS@ -lm
 
 HFILES =       ../include/vorbis/codec.h ../include/vorbis/vorbisfile.h \
-               ../include/vorbis/internal.h ../include/vorbis/backend.h \
+               ../include/vorbis/internal.h ../include/vorbis/backends.h \
                ../include/vorbis/codebook.h \
                bitwise.h envelope.h lpc.h lsp.h bookinternal.h misc.h\
                psy.h smallft.h window.h scales.h os.h mdct.h registry.h
 LFILES =       framing.o mdct.o smallft.o block.o envelope.o window.o\
                lsp.o lpc.o analysis.o synthesis.o psy.o info.o bitwise.o\
                time0.o floor0.o res0.o mapping0.o registry.o\
-               spectrum.o codebook.o vorbisfile.o
+               codebook.o vorbisfile.o
 
 all:
        $(MAKE) target CFLAGS="$(OPT)"
index 74a75cf..c617372 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.23 2000/01/22 13:28:15 xiphmont Exp $
+ last mod: $Id: block.c,v 1.24 2000/01/28 09:05:06 xiphmont Exp $
 
  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
  more amusing by Vorbis' current two allowed block sizes.
@@ -204,11 +204,6 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
                                         vi->map_param[maptype]);
   }
 
-  /* finish the codebooks */
-  v->fullbooks=calloc(vi->books,sizeof(codebook));
-  for(i=0;i<vi->books;i++)
-    vorbis_book_finish(v->fullbooks+i,vi->book_param[i]);
-
   /* initialize the storage vectors to a decent size greater than the
      minimum */
   
@@ -237,9 +232,14 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi){
 
 /* arbitrary settings and spec-mandated numbers get filled in here */
 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
-
+  int i;
   _vds_shared_init(v,vi);
 
+  /* finish the codebooks */
+  v->fullbooks=calloc(vi->books,sizeof(codebook));
+  for(i=0;i<vi->books;i++)
+    vorbis_book_init_encode(v->fullbooks+i,vi->book_param[i]);
+
   /* Initialize the envelope multiplier storage */
 
   v->envelope_storage=v->pcm_storage/vi->envelopesa;
@@ -522,8 +522,14 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
 }
 
 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
+  int i;
   _vds_shared_init(v,vi);
 
+  /* finish the codebooks */
+  v->fullbooks=calloc(vi->books,sizeof(codebook));
+  for(i=0;i<vi->books;i++)
+    vorbis_book_init_decode(v->fullbooks+i,vi->book_param[i]);
+
   /* Adjust centerW to allow an easier mechanism for determining output */
   v->pcm_returned=v->centerW;
   v->centerW-= vi->blocksizes[v->W]/4+vi->blocksizes[v->lW]/4;
index 0d74deb..e5e7b7a 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: basic codebook pack/unpack/code/decode operations
- last mod: $Id: bookinternal.h,v 1.4 2000/01/22 13:28:16 xiphmont Exp $
+ last mod: $Id: bookinternal.h,v 1.5 2000/01/28 09:05:07 xiphmont Exp $
 
  ********************************************************************/
 
 #include "vorbis/codebook.h"
 #include "bitwise.h"
 
-extern void vorbis_book_finish(codebook *dest,const static_codebook *source);
+extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b);
+extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c);
+extern void vorbis_staticbook_clear(static_codebook *b);
+
+extern int vorbis_book_init_encode(codebook *dest,const static_codebook *source);
+extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source);
 extern void vorbis_book_clear(codebook *b);
-extern int vorbis_book_pack(codebook *c,oggpack_buffer *b);
-extern int vorbis_book_unpack(oggpack_buffer *b,codebook *c);
 
 extern int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b);
 extern int vorbis_book_encodev(codebook *book, double *a, oggpack_buffer *b);
index 0990591..a51cf4f 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: basic codebook pack/unpack/code/decode operations
- last mod: $Id: codebook.c,v 1.3 2000/01/22 13:28:17 xiphmont Exp $
+ last mod: $Id: codebook.c,v 1.4 2000/01/28 09:05:08 xiphmont Exp $
 
  ********************************************************************/
 
@@ -33,20 +33,7 @@ static int ilog(unsigned int v){
   return(ret);
 }
 
-static long _float24_pack(double val){
-  int sign=0;
-  long exp;
-  long mant;
-  if(val<0){
-    sign=0x800000;
-    val= -val;
-  }
-  exp= floor(log(val)/log(2));
-  mant=rint(ldexp(val,17-exp));
-  exp=(exp+VQ_FEXP_BIAS)<<18;
-
-  return(sign|exp|mant);
-}
+/* code that packs the 24 bit float can be found in vq/bookutil.c */
 
 static double _float24_unpack(long val){
   double mant=val&0x3ffff;
@@ -121,8 +108,43 @@ long *_make_words(long *l,long n){
   return(r);
 }
 
+/* build the decode helper tree from the codewords */
+decode_aux *_make_decode_tree(codebook *c){
+  const static_codebook *s=c->c;
+  long top=0,i,j;
+  decode_aux *t=malloc(sizeof(decode_aux));
+  long *ptr0=t->ptr0=calloc(c->entries*2,sizeof(long));
+  long *ptr1=t->ptr1=calloc(c->entries*2,sizeof(long));
+  long *codelist=_make_words(s->lengthlist,s->entries);
+
+  if(codelist==NULL)return(NULL);
+  t->aux=c->entries*2;
+
+  for(i=0;i<c->entries;i++){
+    long ptr=0;
+    for(j=0;j<s->lengthlist[i]-1;j++){
+      int bit=(codelist[i]>>j)&1;
+      if(!bit){
+       if(!ptr0[ptr])
+         ptr0[ptr]= ++top;
+       ptr=ptr0[ptr];
+      }else{
+       if(!ptr1[ptr])
+         ptr1[ptr]= ++top;
+       ptr=ptr1[ptr];
+      }
+    }
+    if(!((codelist[i]>>j)&1))
+      ptr0[ptr]=-i;
+    else
+      ptr1[ptr]=-i;
+  }
+  free(codelist);
+  return(t);
+}
+
 /* unpack the quantized list of values for encode/decode ***********/
-static double *_book_unquantize(static_codebook *b){
+static double *_book_unquantize(const static_codebook *b){
   long j,k;
   double mindel=_float24_unpack(b->q_min);
   double delta=_float24_unpack(b->q_delta);
@@ -139,8 +161,23 @@ static double *_book_unquantize(static_codebook *b){
   return(r);
 }
 
+void vorbis_staticbook_clear(static_codebook *b){
+  if(b->quantlist)free(b->quantlist);
+  if(b->lengthlist)free(b->lengthlist);
+  if(b->encode_tree){
+    free(b->encode_tree->ptr0);
+    free(b->encode_tree->ptr1);
+    free(b->encode_tree->p);
+    free(b->encode_tree->q);
+    memset(b->encode_tree,0,sizeof(encode_aux));
+    free(b->encode_tree);
+  }
+  memset(b,0,sizeof(static_codebook));
+}
+
 void vorbis_book_clear(codebook *b){
-  /* static book is not cleared.  It exists only in encode */
+  /* static book is not cleared; we're likely called on the lookup and
+     the static codebook belongs to the info struct */
   if(b->decode_tree){
     free(b->decode_tree->ptr0);
     free(b->decode_tree->ptr1);
@@ -152,19 +189,33 @@ void vorbis_book_clear(codebook *b){
   memset(b,0,sizeof(codebook));
 }
 
-int vorbis_book_finish(codebook *c, static_codebook *s){
+int vorbis_book_init_encode(codebook *c,const static_codebook *s){
+  memset(c,0,sizeof(codebook));
+  c->c=s;
+  c->entries=s->entries;
+  c->dim=s->dim;
+  c->codelist=_make_words(s->lengthlist,s->entries);
+  c->valuelist=_book_unquantize(s);
+  return(0);
+}
+
+int vorbis_book_init_decode(codebook *c,const static_codebook *s){
   memset(c,0,sizeof(codebook));
   c->c=s;
-  c->elements=s->elements;
+  c->entries=s->entries;
   c->dim=s->dim;
-  c->codelist=_make_words(c->lengthlist,c->entries);
-  c->valuelist=_book_unquantize(c);
+  c->valuelist=_book_unquantize(s);
+  c->decode_tree=_make_decode_tree(c);
+  if(c->decode_tree==NULL)goto err_out;
   return(0);
+ err_out:
+  vorbis_book_clear(c);
+  return(-1);
 }
 
 /* packs the given codebook into the bitstream **************************/
 
-int vorbis_book_pack(static_codebook *c,oggpack_buffer *opb){
+int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
   long i,j;
   int ordered=0;
 
@@ -235,45 +286,41 @@ int vorbis_book_pack(static_codebook *c,oggpack_buffer *opb){
 
 /* unpacks a codebook from the packet buffer into the codebook struct,
    readies the codebook auxiliary structures for decode *************/
-int vorbis_book_unpack(oggpack_buffer *opb,codebook *c){
+int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
   long i,j;
-  long *lengthlist=NULL;
-  long *codelist=NULL;
-  static codebook s;
-  memset(c,0,sizeof(codebook));
-  memset(&s,0,sizeof(s));
+  memset(s,0,sizeof(static_codebook));
 
   /* make sure alignment is correct */
   if(_oggpack_read(opb,24)!=0x564342)goto _eofout;
 
   /* first the basic parameters */
-  c->dim=_oggpack_read(opb,16);
-  c->entries=_oggpack_read(opb,24);
-  if(c->entries==-1)goto _eofout;
+  s->dim=_oggpack_read(opb,16);
+  s->entries=_oggpack_read(opb,24);
+  if(s->entries==-1)goto _eofout;
 
   /* codeword ordering.... length ordered or unordered? */
   switch(_oggpack_read(opb,1)){
   case 0:
     /* unordered */
-    lengthlist=malloc(sizeof(long)*c->entries);
-    for(i=0;i<c->entries;i++){
+    s->lengthlist=malloc(sizeof(long)*s->entries);
+    for(i=0;i<s->entries;i++){
       long num=_oggpack_read(opb,5);
       if(num==-1)goto _eofout;
-      lengthlist[i]=num+1;
+      s->lengthlist[i]=num+1;
     }
-
+    
     break;
   case 1:
     /* ordered */
     {
       long length=_oggpack_read(opb,5)+1;
-      lengthlist=malloc(sizeof(long)*c->entries);
-
-      for(i=0;i<c->entries;){
-       long num=_oggpack_read(opb,ilog(c->entries-i));
+      s->lengthlist=malloc(sizeof(long)*s->entries);
+      
+      for(i=0;i<s->entries;){
+       long num=_oggpack_read(opb,ilog(s->entries-i));
        if(num==-1)goto _eofout;
        for(j=0;j<num;j++,i++)
-         lengthlist[i]=length;
+         s->lengthlist[i]=length;
        length++;
       }
     }
@@ -283,60 +330,20 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *c){
     return(-1);
   }
   
-  /* now we generate the codewords for the given lengths */
-  codelist=_make_words(c->lengthlist,c->entries);
-  if(codelist==NULL)goto _errout;
-
-  /* ...and the decode helper tree from the codewords */
-  {
-    long top=0;
-    decode_aux *t=c->decode_tree=malloc(sizeof(decode_aux));
-    long *ptr0=t->ptr0=calloc(c->entries*2,sizeof(long));
-    long *ptr1=t->ptr1=calloc(c->entries*2,sizeof(long));
-    t->aux=c->entries*2;
-
-    for(i=0;i<c->entries;i++){
-      long ptr=0;
-      for(j=0;j<lengthlist[i]-1;j++){
-       int bit=(codelist[i]>>j)&1;
-       if(!bit){
-         if(!ptr0[ptr])
-           ptr0[ptr]= ++top;
-         ptr=ptr0[ptr];
-       }else{
-         if(!ptr1[ptr])
-           ptr1[ptr]= ++top;
-         ptr=ptr1[ptr];
-       }
-      }
-      if(!((codelist[i]>>j)&1))
-       ptr0[ptr]=-i;
-      else
-       ptr1[ptr]=-i;
-    }
-  }
-  /* no longer needed */
-  free(lengthlist);
-  free(codelist);
-
   /* Do we have a mapping to unpack? */
   if(_oggpack_read(opb,1)){
 
     /* values that define the dequantization */
-    s.q_min=_oggpack_read(opb,24);
-    s.q_delta=_oggpack_read(opb,24);
-    s.q_quant=_oggpack_read(opb,4)+1;
-    s.q_sequencep=_oggpack_read(opb,1);
-    s.dim=c->dim;
-    s.entries=c->entries;
+    s->q_min=_oggpack_read(opb,24);
+    s->q_delta=_oggpack_read(opb,24);
+    s->q_quant=_oggpack_read(opb,4)+1;
+    s->q_sequencep=_oggpack_read(opb,1);
 
     /* quantized values */
-    s.quantlist=malloc(sizeof(double)*c->entries*c->dim);
-    for(i=0;i<c->entries*c->dim;i++)
-      s.quantlist[i]=_oggpack_read(opb,s.q_quant);
-    if(s.quantlist[i-1]==-1)goto _eofout;
-    c->valuelist=_book_unquantize(&s);
-    free(s.quantlist);memset(&s,0,sizeof(s));
+    s->quantlist=malloc(sizeof(double)*s->entries*s->dim);
+    for(i=0;i<s->entries*s->dim;i++)
+      s->quantlist[i]=_oggpack_read(opb,s->q_quant);
+    if(s->quantlist[i-1]==-1)goto _eofout;
   }
 
   /* all set */
@@ -344,12 +351,8 @@ int vorbis_book_unpack(oggpack_buffer *opb,codebook *c){
 
  _errout:
  _eofout:
-  if(lengthlist)free(lengthlist);
-  if(s.quantlist)free(s.quantlist);
-  if(codelist)free(codelist);
-  vorbis_book_clear(c);
-  return(-1);
+  vorbis_staticbook_clear(s);
+  return(-1); 
 }
 
 /* returns the number of bits ***************************************/
@@ -539,6 +542,7 @@ int main(){
 
   while(testlist[ptr]){
     codebook c;
+    static_codebook s;
     double *qv=alloca(sizeof(double)*TESTSIZE);
     double *iv=alloca(sizeof(double)*TESTSIZE);
     memcpy(qv,testvec[ptr],sizeof(double)*TESTSIZE);
@@ -547,8 +551,9 @@ int main(){
 
     /* pack the codebook, write the testvector */
     _oggpack_reset(&write);
-    vorbis_book_finish(&c,testlist[ptr]); /* get it into memory we can write */
-    vorbis_book_pack(&c,&write);
+    vorbis_book_init_encode(&c,testlist[ptr]); /* get it into memory
+                                                  we can write */
+    vorbis_book_pack(testlist[ptr],&write);
     fprintf(stderr,"Codebook size %ld bytes... ",_oggpack_bytes(&write));
     for(i=0;i<TESTSIZE;i+=TESTDIM)
       vorbis_book_encodev(&c,qv+i,&write);
@@ -559,10 +564,15 @@ int main(){
 
     /* transfer the write data to a read buffer and unpack/read */
     _oggpack_readinit(&read,_oggpack_buffer(&write),_oggpack_bytes(&write));
-    if(vorbis_book_unpack(&read,&c)){
+    if(vorbis_book_unpack(&read,&s)){
       fprintf(stderr,"Error unpacking codebook.\n");
       exit(1);
     }
+    if(vorbis_book_init_decode(&c,&s)){
+      fprintf(stderr,"Error initializing codebook.\n");
+      exit(1);
+    }
+
     for(i=0;i<TESTSIZE;i+=TESTDIM)
       if(vorbis_book_decodev(&c,iv+i,&read)){
        fprintf(stderr,"Error reading codebook test data (EOP).\n");
index ee5b0f1..ef36f4a 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: floor backend 0 implementation
- last mod: $Id: floor0.c,v 1.2 2000/01/22 13:28:19 xiphmont Exp $
+ last mod: $Id: floor0.c,v 1.3 2000/01/28 09:05:09 xiphmont Exp $
 
  ********************************************************************/
 
 #include "bitwise.h"
 #include "registry.h"
 
+static void free_info(vorbis_info_floor *i){
+  vorbis_info_floor0 *d=(vorbis_info_floor0 *)i;
+  if(d){
+    if(d->books)free(d->books);
+    memset(i,0,sizeof(vorbis_info_floor0));
+  }
+}
+static void free_look(vorbis_look_floor *i){
+}
+
 static void pack (vorbis_info_floor *i,oggpack_buffer *opb){
   vorbis_info_floor0 *d=(vorbis_info_floor0 *)i;
   int j;
@@ -61,17 +71,8 @@ static vorbis_look_floor *look (vorbis_info *vi,vorbis_info_mode *mi,
                               vorbis_info_floor *i){
 
 }
-static void free_info(vorbis_info_floor *i){
-  vorbis_info_floor0 *d=(vorbis_info_floor0 *)i;
-  if(d){
-    if(d->books)free(d->books);
-    memset(i,0,sizeof(vorbis_info_floor0));
-  }
-}
-static void free_look(vorbis_look_floor *i){
-}
 
-static void forward(vorbis_block *vb,vorbis_look_floor *i,
+static int forward(vorbis_block *vb,vorbis_look_floor *i,
                    double *in,double *out){
 
 
@@ -93,8 +94,8 @@ static void forward(vorbis_block *vb,vorbis_look_floor *i,
       vorbis_lpc_to_curve(curve,lpc,vb->amp[i],vl);*/
   return(0);
 }
-static void inverse(vorbis_block *vb,vorbis_look_floor *i,
-                   double *in,double *out){
+static int inverse(vorbis_block *vb,vorbis_look_floor *i,
+                   double *buf){
   return(0);
 }
 
index a423972..cf0eb7b 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: maintain the info structure, info <-> header packets
- last mod: $Id: info.c,v 1.17 2000/01/22 13:28:21 xiphmont Exp $
+ last mod: $Id: info.c,v 1.18 2000/01/28 09:05:10 xiphmont Exp $
 
  ********************************************************************/
 
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "vorbis/codec.h"
+#include "vorbis/backends.h"
 #include "bitwise.h"
 #include "bookinternal.h"
 #include "registry.h"
@@ -29,7 +30,6 @@
 #include "psy.h"
 
 /* helpers */
-
 static int ilog2(unsigned int v){
   int ret=0;
   while(v>1){
@@ -51,71 +51,29 @@ static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
   }
 }
 
-/* convenience functions for the interface */
-int vorbis_dsp_addcomment(vorbis_dsp_state *v,char *comment){
-  vorbis_info *vi=v->vi;
-  vi->user_comments=realloc(vi->user_comments,
-                           (vi->comments+2)*sizeof(char *));
-  vi->user_comments[vi->comments]=strdup(comment);
-  vi->comments++;
-  vi->user_comments[vi->comments]=NULL;
-  return(0);
+void vorbis_comment_init(vorbis_comment *vc){
+  memset(vc,0,sizeof(vorbis_comment));
 }
 
-/* used by analysis, which has a minimally replicated vi */
-void _vorbis_info_anrep(vorbis_info *dest, vorbis_info *source){
-
-/* libVorbis expects modes to be submitted in an already valid
-   vorbis_info structure, but also expects some of the elements to be
-   allocated storage.  To make this easier, the Vorbis distribution
-   includes a number of modes in static storage as headers.  To
-   allocate a copy, run it through vorbis_info_dup */
-
-/* note that due to codebook size, codebooks are not fully duplicated.
-   The info structure (aside from the embedded codebook elements) will
-   be fully dupped */
-
-int vorbis_info_dup(vorbis_info *dest,vorbis_info *source){
-  int i;
-  memcpy(dest,source,sizeof(vorbis_info));
-
-  /* also dup individual pieces that need to be allocated */
-  /* dup user comments (unlikely to have any, but for completeness */
-  if(source->comments>0){
-    dest->user_comments=calloc(source->comments+1,sizeof(char *));
-    for(i=0;i<source->comments;i++)
-      dest->user_comments[i]=strdup(source->user_comments[i]);
-  }
-  dest->vendor=NULL;
-
-  /* modes, maps, times, floors, residues, psychoacoustics are not
-     dupped; the pointer is just replicated by the above copy */
-
-  /* dup (partially) books */
-  if(source->books){
-    dest->booklist=malloc(source->books*sizeof(codebook *));
-    for(i=0;i<source->books;i++){
-      dest->booklist[i]=calloc(1,sizeof(codebook));
-      vorbis_book_dup(dest->booklist[i],source->booklist[i]);
-    }
-  }
-
-  return(0);
-err_out:
-  vorbis_info_clear(dest);
-  return(-1);
+void vorbis_comment_add(vorbis_comment *vc,char *comment){
+  vc->user_comments=realloc(vc->user_comments,
+                           (vc->comments+2)*sizeof(char *));
+  vc->user_comments[vc->comments]=strdup(comment);
+  vc->comments++;
+  vc->user_comments[vc->comments]=NULL;
 }
 
-
-  memset(vi,0,sizeof(vorbis_info));
-}
-
-void vorbis_info_anclear(vorbis_info *vi){
-  memset(vi,0,sizeof(vorbis_info));
+void vorbis_comment_clear(vorbis_comment *vc){
+  if(vc){
+    long i;
+    for(i=0;i<vc->comments;i++)
+      if(vc->user_comments[i])free(vc->user_comments[i]);
+    if(vc->user_comments)free(vc->user_comments);
+    if(vc->vendor)free(vc->vendor);
+  }
+  memset(vc,0,sizeof(vorbis_comment));
 }
 
-
-
 /* used by synthesis, which has a full, alloced vi */
 void vorbis_info_init(vorbis_info *vi){
   memset(vi,0,sizeof(vorbis_info));
@@ -123,62 +81,44 @@ void vorbis_info_init(vorbis_info *vi){
 
 void vorbis_info_clear(vorbis_info *vi){
   int i;
-  if(vi->comments){
-    for(i=0;i<vi->comments;i++)
-      if(vi->user_comments[i])free(vi->user_comments[i]);
-    free(vi->user_comments);
-  }
-  if(vi->vendor)free(vi->vendor);
-  if(vi->windowtypes)free(vi->windowtypes);
-  if(vi->transformtypes)free(vi->transformtypes);
-  if(vi->modes){
-    for(i=0;i<vi->modes;i++)
-      if(vi->mappingtypes[i]>=0 && vi->mappingtypes[i]<VI_MAPB)
-       vorbis_map_free_P[vi->mappingtypes[i]](vi->modelist[i]);
-    free(vi->modelist);
-    free(vi->mappingtypes);
-    free(vi->blockflags);
-  }
-  if(vi->times){
-    for(i=0;i<vi->times;i++)
-      if(vi->timetypes[i]>=0 && vi->timetypes[i]<VI_TIMEB)
-       vorbis_time_free_P[vi->timetypes[i]](vi->timelist[i]);
-    free(vi->timelist);
-    free(vi->timetypes);
-  }
-  if(vi->floors){
-    for(i=0;i<vi->floors;i++)
-      if(vi->floortypes[i]>=0 && vi->floortypes[i]<VI_FLOORB)
-       vorbis_floor_free_P[vi->floortypes[i]](vi->floorlist[i]);
-    free(vi->floorlist);
-    free(vi->floortypes);
-  }
-  if(vi->residues){
-    for(i=0;i<vi->residues;i++)
-      if(vi->residuetypes[i]>=0 && vi->residuetypes[i]<VI_RESB)
-       vorbis_res_free_P[vi->residuetypes[i]](vi->residuelist[i]);
-    free(vi->residuelist);
-    free(vi->residuetypes);
-  }
-  if(vi->books){
-    for(i=0;i<vi->books;i++){
-      if(vi->booklist[i]){
-       vorbis_book_clear(vi->booklist[i]);
-       free(vi->booklist[i]);
-      }
+
+  for(i=0;i<vi->modes;i++)
+    if(vi->mode_param[i])free(vi->mode_param[i]);
+  if(vi->mode_param)free(vi->mode_param);
+  for(i=0;i<vi->maps;i++) /* unpack does the range checking */
+    _mapping_P[i]->free_info(vi->map_param[i]);
+  if(vi->map_param)free(vi->map_param);
+    
+  for(i=0;i<vi->times;i++) /* unpack does the range checking */
+    _time_P[i]->free_info(vi->time_param[i]);
+  if(vi->time_param)free(vi->time_param);
+    
+  for(i=0;i<vi->floors;i++) /* unpack does the range checking */
+    _floor_P[i]->free_info(vi->floor_param[i]);
+  if(vi->floor_param)free(vi->floor_param);
+    
+  for(i=0;i<vi->residues;i++) /* unpack does the range checking */
+    _residue_P[i]->free_info(vi->residue_param[i]);
+  if(vi->residue_param)free(vi->residue_param);
+
+  /* the static codebooks *are* freed if you call info_clear, because
+     decode side does alloc a 'static' codebook. Calling clear on the
+     full codebook does not clear the static codebook (that's our
+     responsibility) */
+  for(i=0;i<vi->books;i++){
+    /* just in case the decoder pre-cleared to save space */
+    if(vi->book_param[i]){
+      vorbis_staticbook_clear(vi->book_param[i]);
+      free(vi->book_param[i]);
     }
-    free(vi->booklist);
   }
-  if(vi->psys){
-    for(i=0;i<vi->psys;i++)
-      _vi_psy_free(vi->psylist[i]);
-    free(vi->psylist);
-  }
-  
-  if(vi->header)free(vi->header);
-  if(vi->header1)free(vi->header1);
-  if(vi->header2)free(vi->header2);
+  if(vi->book_param)free(vi->book_param);
 
+  for(i=0;i<vi->psys;i++)
+    _vi_psy_free(vi->psy_param[i]);
+  if(vi->psy_param)free(vi->psy_param);
+  
   memset(vi,0,sizeof(vorbis_info));
 }
 
@@ -211,27 +151,27 @@ static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
   return(-1);
 }
 
-static int _vorbis_unpack_comments(vorbis_info *vi,oggpack_buffer *opb){
+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;
-  vi->vendor=calloc(vendorlen+1,1);
-  _v_readstring(opb,vi->vendor,vendorlen);
-  vi->comments=_oggpack_read(opb,32);
-  if(vi->comments<0)goto err_out;
-  vi->user_comments=calloc(vi->comments+1,sizeof(char **));
+  vc->vendor=calloc(vendorlen+1,1);
+  _v_readstring(opb,vc->vendor,vendorlen);
+  vc->comments=_oggpack_read(opb,32);
+  if(vc->comments<0)goto err_out;
+  vc->user_comments=calloc(vc->comments+1,sizeof(char **));
            
-  for(i=0;i<vi->comments;i++){
+  for(i=0;i<vc->comments;i++){
     int len=_oggpack_read(opb,32);
     if(len<0)goto err_out;
-    vi->user_comments[i]=calloc(len+1,1);
-    _v_readstring(opb,vi->user_comments[i],len);
+    vc->user_comments[i]=calloc(len+1,1);
+    _v_readstring(opb,vc->user_comments[i],len);
   }      
   if(_oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
 
   return(0);
  err_out:
-  vorbis_info_clear(vi);
+  vorbis_comment_clear(vc);
   return(-1);
 }
 
@@ -240,71 +180,77 @@ static int _vorbis_unpack_comments(vorbis_info *vi,oggpack_buffer *opb){
 static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
   int i;
 
+  /* codebooks */
+  vi->books=_oggpack_read(opb,16);
+  vi->book_param=calloc(vi->books,sizeof(static_codebook *));
+  for(i=0;i<vi->books;i++){
+    vi->book_param[i]=calloc(1,sizeof(static_codebook));
+    if(vorbis_staticbook_unpack(opb,vi->book_param[i]))goto err_out;
+  }
+
   /* time backend settings */
   vi->times=_oggpack_read(opb,8);
-  vi->timetypes=malloc(vi->times*sizeof(int));
-  vi->timelist=calloc(vi->times,sizeof(void *));
+  vi->time_type=malloc(vi->times*sizeof(int));
+  vi->time_param=calloc(vi->times,sizeof(void *));
   for(i=0;i<vi->times;i++){
-    vi->timetypes[i]=_oggpack_read(opb,16);
-    if(vi->timetypes[i]<0 || vi->timetypes[i]>VI_TIMEB)goto err_out;
-    vi->timelist[i]=vorbis_time_unpack_P[vi->timetypes[i]](vi,opb);
-    if(!vi->timelist[i])goto err_out;
+    vi->time_type[i]=_oggpack_read(opb,16);
+    if(vi->time_type[i]<0 || vi->time_type[i]>=VI_TIMEB)goto err_out;
+    vi->time_param[i]=_time_P[vi->time_type[i]]->unpack(vi,opb);
+    if(!vi->time_param[i])goto err_out;
   }
 
   /* floor backend settings */
   vi->floors=_oggpack_read(opb,8);
-  vi->floortypes=malloc(vi->floors*sizeof(int));
-  vi->floorlist=calloc(vi->floors,sizeof(void *));
+  vi->floor_type=malloc(vi->floors*sizeof(int));
+  vi->floor_param=calloc(vi->floors,sizeof(void *));
   for(i=0;i<vi->floors;i++){
-    vi->floortypes[i]=_oggpack_read(opb,16);
-    if(vi->floortypes[i]<0 || vi->floortypes[i]>VI_FLOORB)goto err_out;
-    vi->floorlist[i]=vorbis_floor_unpack_P[vi->floortypes[i]](vi,opb);
-    if(!vi->floorlist[i])goto err_out;
+    vi->floor_type[i]=_oggpack_read(opb,16);
+    if(vi->floor_type[i]<0 || vi->floor_type[i]>=VI_FLOORB)goto err_out;
+    vi->floor_param[i]=_floor_P[vi->floor_type[i]]->unpack(vi,opb);
+    if(!vi->floor_param[i])goto err_out;
   }
 
   /* residue backend settings */
   vi->residues=_oggpack_read(opb,8);
-  vi->residuetypes=malloc(vi->residues*sizeof(int));
-  vi->residuelist=calloc(vi->residues,sizeof(void *));
+  vi->residue_type=malloc(vi->residues*sizeof(int));
+  vi->residue_param=calloc(vi->residues,sizeof(void *));
   for(i=0;i<vi->residues;i++){
-    vi->residuetypes[i]=_oggpack_read(opb,16);
-    if(vi->residuetypes[i]<0 || vi->residuetypes[i]>VI_RESB)goto err_out;
-    vi->residuelist[i]=vorbis_res_unpack_P[vi->residuetypes[i]](vi,opb);
-    if(!vi->residuelist[i])goto err_out;
+    vi->residue_type[i]=_oggpack_read(opb,16);
+    if(vi->residue_type[i]<0 || vi->residue_type[i]>=VI_RESB)goto err_out;
+    vi->residue_param[i]=_residue_P[vi->residue_type[i]]->unpack(vi,opb);
+    if(!vi->residue_param[i])goto err_out;
   }
 
-  /* codebooks */
-  vi->books=_oggpack_read(opb,16);
-  vi->booklist=calloc(vi->books,sizeof(codebook *));
-  for(i=0;i<vi->books;i++){
-    vi->booklist[i]=calloc(1,sizeof(codebook));
-    if(vorbis_book_unpack(opb,vi->booklist[i]))goto err_out;
+  /* map backend settings */
+  vi->maps=_oggpack_read(opb,8);
+  vi->map_type=malloc(vi->maps*sizeof(int));
+  vi->map_param=calloc(vi->maps,sizeof(void *));
+  for(i=0;i<vi->maps;i++){
+    vi->map_type[i]=_oggpack_read(opb,16);
+    if(vi->map_type[i]<0 || vi->map_type[i]>=VI_MAPB)goto err_out;
+    vi->map_param[i]=_mapping_P[vi->map_type[i]]->unpack(vi,opb);
+    if(!vi->map_param[i])goto err_out;
   }
-
-  /* modes/mappings; these are loaded last in order that the mappings
-     can range-check their time/floor/res/book settings */
+  
+  /* mode settings */
   vi->modes=_oggpack_read(opb,8);
-  vi->blockflags=malloc(vi->modes*sizeof(int));
-  vi->windowtypes=malloc(vi->modes*sizeof(int));
-  vi->transformtypes=malloc(vi->modes*sizeof(int));
-  vi->mappingtypes=malloc(vi->modes*sizeof(int));
-  vi->modelist=calloc(vi->modes,sizeof(void *));
+  vi->mode_param=calloc(vi->modes,sizeof(void *));
   for(i=0;i<vi->modes;i++){
-    vi->blockflags[i]=_oggpack_read(opb,1);
-    vi->windowtypes[i]=_oggpack_read(opb,16);
-    vi->transformtypes[i]=_oggpack_read(opb,16);
-    vi->mappingtypes[i]=_oggpack_read(opb,16);
-    if(vi->windowtypes[i]<0 || vi->windowtypes[i]>VI_WINDOWB)goto err_out;
-    if(vi->transformtypes[i]<0 || vi->transformtypes[i]>VI_TRANSFORMB)goto err_out;
-    if(vi->mappingtypes[i]<0 || vi->mappingtypes[i]>VI_MAPB)goto err_out;
-    vi->modelist[i]=vorbis_map_unpack_P[vi->mappingtypes[i]](vi,opb);
-    if(!vi->modelist[i])goto err_out;
+    vi->mode_param[i]=calloc(1,sizeof(vorbis_info_mode));
+    vi->mode_param[i]->blockflag=_oggpack_read(opb,1);
+    vi->mode_param[i]->windowtype=_oggpack_read(opb,16);
+    vi->mode_param[i]->transformtype=_oggpack_read(opb,16);
+    vi->mode_param[i]->mapping=_oggpack_read(opb,8);
+
+    if(vi->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
+    if(vi->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
+    if(vi->mode_param[i]->mapping>=vi->maps)goto err_out;
   }
-
+  
   if(_oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
 
   return(0);
-err_out:
+ err_out:
   vorbis_info_clear(vi);
   return(-1);
 }
@@ -314,8 +260,7 @@ err_out:
    with bitstream comments and a third packet that holds the
    codebook. */
 
-int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
-
+int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
   oggpack_buffer opb;
   
   if(op){
@@ -350,10 +295,10 @@ int vorbis_info_headerin(vorbis_info *vi,ogg_packet *op){
          return(-1);
        }
 
-       return(_vorbis_unpack_comments(vi,&opb));
+       return(_vorbis_unpack_comment(vc,&opb));
 
       case 0x82:
-       if(vi->rate==0 || vi->vendor==NULL){
+       if(vi->rate==0 || vc->vendor==NULL){
          /* um... we didn;t get the initial header or comments yet */
          return(-1);
        }
@@ -393,8 +338,8 @@ static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
   return(0);
 }
 
-static int _vorbis_pack_comments(oggpack_buffer *opb,vorbis_info *vi){
-  char temp[]="Xiphophorus libVorbis I 20000114";
+static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
+  char temp[]="Xiphophorus libVorbis I 20000121";
 
   /* preamble */  
   _v_writestring(opb,"vorbis");
@@ -406,13 +351,13 @@ static int _vorbis_pack_comments(oggpack_buffer *opb,vorbis_info *vi){
   
   /* comments */
 
-  _oggpack_write(opb,vi->comments,32);
-  if(vi->comments){
+  _oggpack_write(opb,vc->comments,32);
+  if(vc->comments){
     int i;
-    for(i=0;i<vi->comments;i++){
-      if(vi->user_comments[i]){
-       _oggpack_write(opb,strlen(vi->user_comments[i]),32);
-       _v_writestring(opb,vi->user_comments[i]);
+    for(i=0;i<vc->comments;i++){
+      if(vc->user_comments[i]){
+       _oggpack_write(opb,strlen(vc->user_comments[i]),32);
+       _v_writestring(opb,vc->user_comments[i]);
       }else{
        _oggpack_write(opb,0,32);
       }
@@ -428,43 +373,47 @@ static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
   _v_writestring(opb,"vorbis");
   _oggpack_write(opb,0x82,8);
 
+  /* books */
+  _oggpack_write(opb,vi->books,16);
+  for(i=0;i<vi->books;i++)
+    if(vorbis_staticbook_pack(vi->book_param[i],opb))goto err_out;
+
   /* times */
   _oggpack_write(opb,vi->times,8);
   for(i=0;i<vi->times;i++){
-    _oggpack_write(opb,vi->timetypes[i],16);
-    vorbis_time_pack_P[vi->timetypes[i]](opb,vi->timelist[i]);
+    _oggpack_write(opb,vi->time_type[i],16);
+    _time_P[vi->time_type[i]]->pack(vi->time_param[i],opb);
   }
 
   /* floors */
   _oggpack_write(opb,vi->floors,8);
   for(i=0;i<vi->floors;i++){
-    _oggpack_write(opb,vi->floortypes[i],16);
-    vorbis_floor_pack_P[vi->floortypes[i]](opb,vi->floorlist[i]);
+    _oggpack_write(opb,vi->floor_type[i],16);
+    _floor_P[vi->floor_type[i]]->pack(vi->floor_param[i],opb);
   }
 
   /* residues */
   _oggpack_write(opb,vi->residues,8);
   for(i=0;i<vi->residues;i++){
-    _oggpack_write(opb,vi->residuetypes[i],16);
-    vorbis_res_pack_P[vi->residuetypes[i]](opb,vi->residuelist[i]);
+    _oggpack_write(opb,vi->residue_type[i],16);
+    _residue_P[vi->residue_type[i]]->pack(vi->residue_param[i],opb);
   }
 
-  /* books */
-  _oggpack_write(opb,vi->books,16);
-  for(i=0;i<vi->books;i++)
-    if(vorbis_book_pack(vi->booklist[i],opb))goto err_out;
-
-  /* mode mappings */
+  /* maps */
+  _oggpack_write(opb,vi->maps,8);
+  for(i=0;i<vi->maps;i++){
+    _oggpack_write(opb,vi->map_type[i],16);
+    _mapping_P[vi->map_type[i]]->pack(vi,vi->map_param[i],opb);
+  }
 
+  /* modes */
   _oggpack_write(opb,vi->modes,8);
   for(i=0;i<vi->modes;i++){
-    _oggpack_write(opb,vi->blockflags[i],1);
-    _oggpack_write(opb,vi->windowtypes[i],16);
-    _oggpack_write(opb,vi->transformtypes[i],16);
-    _oggpack_write(opb,vi->mappingtypes[i],16);
-    vorbis_map_pack_P[vi->mappingtypes[i]](vi,opb,vi->modelist[i]);
+    _oggpack_write(opb,vi->mode_param[i]->blockflag,1);
+    _oggpack_write(opb,vi->mode_param[i]->windowtype,16);
+    _oggpack_write(opb,vi->mode_param[i]->transformtype,16);
+    _oggpack_write(opb,vi->mode_param[i]->mapping,8);
   }
-
   _oggpack_write(opb,1,1);
 
   return(0);
@@ -473,6 +422,7 @@ err_out:
 } 
 
 int vorbis_analysis_headerout(vorbis_dsp_state *v,
+                             vorbis_comment *vc,
                              ogg_packet *op,
                              ogg_packet *op_comm,
                              ogg_packet *op_code){
@@ -499,7 +449,7 @@ int vorbis_analysis_headerout(vorbis_dsp_state *v,
   _oggpack_reset(&opb);
   _v_writestring(&opb,"vorbis");
   _oggpack_write(&opb,0x81,8);
-  if(_vorbis_pack_comments(&opb,vi))goto err_out;
+  if(_vorbis_pack_comment(&opb,vc))goto err_out;
 
   if(v->header1)free(v->header1);
   v->header1=malloc(_oggpack_bytes(&opb));
@@ -533,6 +483,13 @@ int vorbis_analysis_headerout(vorbis_dsp_state *v,
   memset(op,0,sizeof(ogg_packet));
   memset(op_comm,0,sizeof(ogg_packet));
   memset(op_code,0,sizeof(ogg_packet));
+
+  if(v->header)free(v->header);
+  if(v->header1)free(v->header1);
+  if(v->header2)free(v->header2);
+  v->header=NULL;
+  v->header1=NULL;
+  v->header2=NULL;
   return(-1);
 }
 
index 95f4e23..49483b5 100644 (file)
--- a/lib/lpc.c
+++ b/lib/lpc.c
@@ -12,7 +12,7 @@
  ********************************************************************
 
   function: LPC low level routines
-  last mod: $Id: lpc.c,v 1.14 2000/01/20 04:43:01 xiphmont Exp $
+  last mod: $Id: lpc.c,v 1.15 2000/01/28 09:05:11 xiphmont Exp $
 
  ********************************************************************/
 
@@ -352,23 +352,6 @@ void vorbis_lpc_to_curve(double *curve,double *lpc,double amp,lpc_lookup *l){
 #endif
 }
 
-void vorbis_lpc_apply(double *residue,double *lpc,double amp,lpc_lookup *l){
-  double *lcurve=alloca(sizeof(double)*((l->ln+l->n)*2));
-  int i;
-
-  if(amp==0){
-    memset(residue,0,l->n*sizeof(double));
-  }else{
-    
-    _vlpc_de_helper(lcurve,lpc,amp,l);
-
-    for(i=0;i<l->ln;i++)lcurve[i]/=l->barknorm[i];
-    for(i=0;i<l->n;i++)
-      if(residue[i]!=0)
-       residue[i]*=lcurve[l->linearmap[i]];
-  }
-}
-
 /* subtract or add an lpc filter to data.  Vorbis doesn't actually use this. */
 
 void vorbis_lpc_residue(double *coeff,double *prime,int m,
index fe39ec8..21d4912 100644 (file)
--- a/lib/lpc.h
+++ b/lib/lpc.h
@@ -12,7 +12,7 @@
  ********************************************************************
 
   function: LPC low level routines
-  last mod: $Id: lpc.h,v 1.8 2000/01/22 13:28:22 xiphmont Exp $
+  last mod: $Id: lpc.h,v 1.9 2000/01/28 09:05:12 xiphmont Exp $
 
  ********************************************************************/
 
@@ -45,8 +45,6 @@ extern double vorbis_lpc_from_spectrum(double *curve,double *lpc,lpc_lookup *l);
 extern double vorbis_curve_to_lpc(double *curve,double *lpc,lpc_lookup *l);
 extern void vorbis_lpc_to_curve(double *curve,double *lpc, double amp,
                                lpc_lookup *l);
-extern void vorbis_lpc_apply(double *residue,double *lpc, double amp,
-                            lpc_lookup *l);
 
 /* standard lpc stuff */
 extern void vorbis_lpc_residue(double *coeff,double *prime,int m,
index 6339190..0ac237f 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.2 2000/01/22 13:28:23 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.3 2000/01/28 09:05:13 xiphmont Exp $
 
  ********************************************************************/
 
 #include <string.h>
 #include <math.h>
 #include "vorbis/codec.h"
+#include "vorbis/backends.h"
 #include "bitwise.h"
 #include "bookinternal.h"
 #include "registry.h"
-#include "mapping0.h"
+#include "psy.h"
+#include "misc.h"
 
-_vi_info_map *_vorbis_map0_dup(vorbis_info *vi,_vi_info_map *source){
-  vorbis_info_mapping0 *d=malloc(sizeof(vorbis_info_mapping0));
-  vorbis_info_mapping0 *s=(vorbis_info_mapping0 *)source;
-  memcpy(d,s,sizeof(vorbis_info_mapping0));
+/* 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.
 
-  d->floorsubmap=malloc(sizeof(int)*vi->channels);
-  d->residuesubmap=malloc(sizeof(int)*vi->channels);
-  d->psysubmap=malloc(sizeof(int)*vi->channels);
-  memcpy(d->floorsubmap,s->floorsubmap,sizeof(int)*vi->channels);
-  memcpy(d->residuesubmap,s->residuesubmap,sizeof(int)*vi->channels);
-  memcpy(d->psysubmap,s->psysubmap,sizeof(int)*vi->channels);
+   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 */
 
-  return(d);
-}
+typedef struct {
+  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;
+
+} vorbis_look_mapping0;
 
-void _vorbis_map0_free(_vi_info_map *i){
+void free_info(vorbis_info_mapping *i){
   vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)i;
 
   if(d){
+    if(d->chmuxlist)free(d->chmuxlist);
+    if(d->timesubmap)free(d->timesubmap);
     if(d->floorsubmap)free(d->floorsubmap);
     if(d->residuesubmap)free(d->residuesubmap);
     if(d->psysubmap)free(d->psysubmap);
@@ -52,80 +65,118 @@ void _vorbis_map0_free(_vi_info_map *i){
   }
 }
 
-void _vorbis_map0_pack(vorbis_info *vi,oggpack_buffer *opb,
-                             _vi_info_map *source){
+void free_look(vorbis_look_mapping *look){
   int i;
-  vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)source;
-
-  _oggpack_write(opb,d->timesubmap,8);
-
-  /* we abbreviate the channel submappings if they all map to the same
-     floor/res/psy */
-  for(i=1;i<vi->channels;i++)if(d->floorsubmap[i]!=d->floorsubmap[i-1])break;
-  if(i==vi->channels){
-    _oggpack_write(opb,0,1);
-    _oggpack_write(opb,d->floorsubmap[0],8);
-  }else{
-    _oggpack_write(opb,1,1);
-    for(i=0;i<vi->channels;i++)
-      _oggpack_write(opb,d->floorsubmap[i],8);
+  vorbis_look_mapping0 *l=(vorbis_look_mapping0 *)look;
+  if(l){
+    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);
+    }
+    free(l->time_func);
+    free(l->floor_func);
+    free(l->residue_func);
+    free(l->time_look);
+    free(l->floor_look);
+    free(l->residue_look);
+    if(l->psy_look)free(l->psy_look);
+    memset(l,0,sizeof(vorbis_info_mapping0));
+    free(l);
+  }
+}
+
+vorbis_look_mapping *look(vorbis_info *vi,vorbis_info_mode *vm,
+                         vorbis_info_mapping *m){
+  int i;
+  vorbis_look_mapping0 *ret=calloc(1,sizeof(vorbis_look_mapping0));
+  vorbis_info_mapping0 *map=ret->map=(vorbis_info_mapping0 *)m;
+  ret->mode=vm;
+  
+  ret->time_look=calloc(map->submaps,sizeof(vorbis_look_time *));
+  ret->floor_look=calloc(map->submaps,sizeof(vorbis_look_floor *));
+  ret->residue_look=calloc(map->submaps,sizeof(vorbis_look_residue *));
+  ret->psy_look=calloc(map->submaps,sizeof(vorbis_look_psy));
+
+  ret->time_func=calloc(map->submaps,sizeof(vorbis_func_time *));
+  ret->floor_func=calloc(map->submaps,sizeof(vorbis_func_floor *));
+  ret->residue_func=calloc(map->submaps,sizeof(vorbis_func_residue *));
+  
+  for(i=0;i<map->submaps;i++){
+    int timenum=map->timesubmap[i];
+    int floornum=map->floorsubmap[i];
+    int resnum=map->residuesubmap[i];
+
+    ret->time_func[i]=_time_P[vi->time_type[timenum]];
+    ret->time_look[i]=ret->time_func[i]->
+      look(vi,vm,vi->time_param[timenum]);
+    ret->floor_func[i]=_floor_P[vi->floor_type[floornum]];
+    ret->floor_look[i]=ret->floor_func[i]->
+      look(vi,vm,vi->floor_param[floornum]);
+    ret->residue_func[i]=_residue_P[vi->residue_type[resnum]];
+    ret->residue_look[i]=ret->residue_func[i]->
+      look(vi,vm,vi->residue_param[resnum]);
+    
+    if(map->psysubmap){
+      int psynum=map->psysubmap[i];
+      _vp_psy_init(ret->psy_look+i,vi->psy_param[psynum],
+                  vi->blocksizes[vm->blockflag],vi->rate);
+    }
   }
 
-  for(i=1;i<vi->channels;i++)
-    if(d->residuesubmap[i]!=d->residuesubmap[i-1])break;
-  if(i==vi->channels){
-    /* no channel submapping */
-    _oggpack_write(opb,0,1);
-    _oggpack_write(opb,d->residuesubmap[0],8);
-  }else{
-    /* channel submapping */
-    _oggpack_write(opb,1,1);
+  return(ret);
+}
+
+void pack(vorbis_info *vi,vorbis_info_mapping *vm,oggpack_buffer *opb){
+  int i;
+  vorbis_info_mapping0 *d=(vorbis_info_mapping0 *)vm;
+
+  _oggpack_write(opb,d->submaps,4);
+  /* we don't write the channel submappings if we only have one... */
+  if(d->submaps>1){
     for(i=0;i<vi->channels;i++)
-      _oggpack_write(opb,d->residuesubmap[i],8);
+      _oggpack_write(opb,d->chmuxlist[i],4);
+  }
+  for(i=0;i<d->submaps;i++){
+    _oggpack_write(opb,d->timesubmap[i],8);
+    _oggpack_write(opb,d->floorsubmap[i],8);
+    _oggpack_write(opb,d->residuesubmap[i],8);
   }
 }
 
 /* also responsible for range checking */
-extern _vi_info_map *_vorbis_map0_unpack(vorbis_info *vi,oggpack_buffer *opb){
+vorbis_info_mapping *unpack(vorbis_info *vi,oggpack_buffer *opb){
   int i;
   vorbis_info_mapping0 *d=calloc(1,sizeof(vorbis_info_mapping0));
   memset(d,0,sizeof(vorbis_info_mapping0));
 
-  d->timesubmap=_oggpack_read(opb,8);
-  if(d->timesubmap>=vi->times)goto err_out;
+  d->submaps=_oggpack_read(opb,4);
 
-  d->floorsubmap=malloc(sizeof(int)*vi->channels);
-  if(_oggpack_read(opb,1)){
-    /* channel submap */
-    for(i=0;i<vi->channels;i++)
-      d->floorsubmap[i]=_oggpack_read(opb,8);
-  }else{
-    int temp=_oggpack_read(opb,8);
-    for(i=0;i<vi->channels;i++)
-      d->floorsubmap[i]=temp;
-  }
+  d->chmuxlist=calloc(vi->channels,sizeof(int));
+  d->timesubmap=malloc(sizeof(int)*d->submaps);
+  d->floorsubmap=malloc(sizeof(int)*d->submaps);
+  d->residuesubmap=malloc(sizeof(int)*d->submaps);
 
-  d->residuesubmap=malloc(sizeof(int)*vi->channels);
-  if(_oggpack_read(opb,1)){
-    /* channel submap */
-    for(i=0;i<vi->channels;i++)
-      d->residuesubmap[i]=_oggpack_read(opb,8);
-  }else{
-    int temp=_oggpack_read(opb,8);
-    for(i=0;i<vi->channels;i++)
-      d->residuesubmap[i]=temp;
+  if(d->submaps>1){
+    for(i=0;i<vi->channels;i++){
+      d->chmuxlist[i]=_oggpack_read(opb,4);
+      if(d->chmuxlist[i]>=d->submaps)goto err_out;
+    }
   }
-
-  for(i=0;i<vi->channels;i++){
-    if(d->floorsubmap[i]<0 || d->floorsubmap[i]>=vi->floors)goto err_out;
-    if(d->residuesubmap[i]<0 || d->residuesubmap[i]>=vi->residues)
-      goto err_out;
+  for(i=0;i<d->submaps;i++){
+    d->timesubmap[i]=_oggpack_read(opb,8);
+    if(d->timesubmap[i]>=vi->times)goto err_out;
+    d->floorsubmap[i]=_oggpack_read(opb,8);
+    if(d->floorsubmap[i]>=vi->floors)goto err_out;
+    d->residuesubmap[i]=_oggpack_read(opb,8);
+    if(d->residuesubmap[i]>=vi->residues)goto err_out;
   }
 
   return d;
 
  err_out:
-  _vorbis_map0_free(d);
+  free_info(d);
   return(NULL);
 }
 
@@ -140,110 +191,144 @@ extern _vi_info_map *_vorbis_map0_unpack(vorbis_info *vi,oggpack_buffer *opb){
 #include "spectrum.h"
 
 /* no time mapping implementation for now */
-int _vorbis_map0_analysis(int mode,vorbis_block *vb){
+int forward(vorbis_block *vb,vorbis_look_mapping *l){
   vorbis_dsp_state     *vd=vb->vd;
-  oggpack_buffer       *opb=&vb->opb;
   vorbis_info          *vi=vd->vi;
-  vorbis_info_mapping0 *map=(vorbis_info_mapping0 *)(vi->modelist[mode]);
+  vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
+  vorbis_info_mapping0 *map=look->map;
+  vorbis_info_mode     *mode=look->mode;
   int                   n=vb->pcmend;
   int i,j;
+  double *window=vd->window[vb->W][vb->lW][vb->nW][mode->windowtype];
+
+  double **pcmbundle=alloca(sizeof(double *)*vi->channels);
+  int **auxbundle=alloca(sizeof(int *)*vi->channels);
 
   /* time domain pre-window: NONE IMPLEMENTED */
 
   /* window the PCM data: takes PCM vector, vb; modifies PCM vector */
 
-  {
-    double *window=vd->window[vb->W][vb->lW][vb->nW][vi->windowtypes[mode]];
-    for(i=0;i<vi->channels;i++){
-      double *pcm=vb->pcm[i];
-      for(j=0;j<n;j++)
-       pcm[j]*=window[j];
-    }
+  for(i=0;i<vi->channels;i++){
+    double *pcm=vb->pcm[i];
+    for(j=0;j<n;j++)
+      pcm[j]*=window[j];
   }
            
   /* time-domain post-window: NONE IMPLEMENTED */
 
   /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
   /* only MDCT right now.... */
-  {
-    for(i=0;i<vi->channels;i++){
-      double *pcm=vb->pcm[i];
-      mdct_forward(vd->transform[vb->W][0],pcm,pcm);
-    }
+  for(i=0;i<vi->channels;i++){
+    double *pcm=vb->pcm[i];
+    mdct_forward(vd->transform[vb->W][0],pcm,pcm);
   }
 
   {
     double *decfloor=_vorbis_block_alloc(vb,n*sizeof(double)/2);
     double *floor=_vorbis_block_alloc(vb,n*sizeof(double)/2);
     double *mask=_vorbis_block_alloc(vb,n*sizeof(double)/2);
-
+    int **pcmaux=_vorbis_block_alloc(vb,vi->channels*sizeof(int *));
+    
     for(i=0;i<vi->channels;i++){
       double *pcm=vb->pcm[i];
-      double *pcmaux=vb->pcm[i]+n/2;
-      int floorsub=map->floorsubmap[i];
-      int ressub=map->residuesubmap[i];
-      int psysub=map->psysubmap[i];
-      
+      int submap=map->chmuxlist[i];
+
+      pcmaux[i]=_vorbis_block_alloc(vb,n/2*sizeof(int));
       /* perform psychoacoustics; takes PCM vector; 
         returns two curves: the desired transform floor and the masking curve */
       memset(floor,0,sizeof(double)*n/2);
       memset(mask,0,sizeof(double)*n/2);
-      _vp_mask_floor(&vd->psy[psysub],pcm,mask,floor);
+      _vp_mask_floor(look->psy_look+submap,pcm,mask,floor);
  
       /* perform floor encoding; takes transform floor, returns decoded floor */
-      vorbis_floor_encode_P[vi->floortypes[floorsub]]
-       (vi->floorlist[floorsub],vd->floor[floorsub],pcm,floor,decfloor);
-
-      /* perform residue prequantization */
-      _vp_quantize(&vd->psy[psysub],pcm,mask,decfloor,pcmaux);
+      look->floor_func[submap]->
+       forward(vb,look->floor_look[submap],floor,decfloor);
 
+      /* no iterative residue/floor tuning at the moment */
+      
+      /* perform residue prequantization.  Do it now so we have all
+         the values if we need them */
+      _vp_quantize(look->psy_look+submap,pcm,mask,decfloor,pcmaux[i]);
+      
+    }
+  
+    /* 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<map->submaps;i++){
+      int ch_in_bundle=0;
+      for(j=0;j<vi->channels;j++){
+      if(map->chmuxlist[j]==i)
+       pcmbundle[ch_in_bundle]=vb->pcm[j];
+       auxbundle[ch_in_bundle++]=pcmaux[j];
+      }
+      
+      look->residue_func[i]->forward(vb,look->residue_look[i],pcmbundle,auxbundle,
+                                ch_in_bundle);
     }
   }
 
-  /* perform residue encoding with residue mapping; this is multiplexed */
-  /* multiplexing works like this: The first 
-
-  vorbis_res_encode_P[vi->restypes[ressub]]
-       (vi->reslist[ressub],vd->residue[ressub],pcm,mask,decfloor);
-
-
-
   return(0);
 }
 
-int _vorbis_map0_synthesis(int mode,vorbis_block *vb){
-
-
-
-  window=vb->vd->window[vb->W][vb->lW][vb->nW];
-
-  n=vb->pcmend=vi->blocksize[vb->W];
+int inverse(vorbis_block *vb,vorbis_look_mapping *l){
+  vorbis_dsp_state     *vd=vb->vd;
+  vorbis_info          *vi=vd->vi;
+  vorbis_look_mapping0 *look=(vorbis_look_mapping0 *)l;
+  vorbis_info_mapping0 *map=look->map;
+  vorbis_info_mode     *mode=look->mode;
+  int                   i,j;
+  long                  n=vb->pcmend=vi->blocksizes[vb->W];
+
+  double *window=vd->window[vb->W][vb->lW][vb->nW][mode->windowtype];
+  double **pcmbundle=alloca(sizeof(double *)*vi->channels);
   
-  /* No envelope encoding yet */
-  _oggpack_read(opb,0,1);
+  /* 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++){
-    double *lpc=vb->lpc[i];
-    double *lsp=vb->lsp[i];
-    
-    /* recover the spectral envelope */
-    if(_vs_spectrum_decode(vb,&vb->amp[i],lsp)<0)return(-1);
-    
-    /* recover the spectral residue */  
-    if(_vs_residue_decode(vb,vb->pcm[i])<0)return(-1);
+    double *pcm=vb->pcm[i];
+    int submap=map->chmuxlist[i];
+    look->floor_func[submap]->inverse(vb,look->floor_look[submap],pcm);
+  }
 
-    /* LSP->LPC */
-    vorbis_lsp_to_lpc(lsp,lpc,vl->m); 
+  /* recover the residue, apply directly to the spectral envelope */
+  for(i=0;i<map->submaps;i++){
+    int ch_in_bundle=0;
+    for(j=0;j<vi->channels;j++){
+      if(map->chmuxlist[j]==i)
+       pcmbundle[ch_in_bundle++]=vb->pcm[j];
+    }
 
-    /* apply envelope to residue */
-    
-    vorbis_lpc_apply(vb->pcm[i],lpc,vb->amp[i],vl);
-      
+    look->residue_func[i]->inverse(vb,look->residue_look[i],pcmbundle,ch_in_bundle);
+  }
 
-    /* MDCT->time */
-    mdct_backward(&vb->vd->vm[vb->W],vb->pcm[i],vb->pcm[i],window);
-    
+  /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
+  /* only MDCT right now.... */
+  for(i=0;i<vi->channels;i++){
+    double *pcm=vb->pcm[i];
+    mdct_backward(vd->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++){
+    double *pcm=vb->pcm[i];
+    for(j=0;j<n;j++)
+      pcm[j]*=window[j];
+  }
+           
+  /* now apply the decoded post-window time information */
+  /* NOT IMPLEMENTED */
+
+  /* all done! */
   return(0);
 }
 
index c138ec8..a5170b7 100644 (file)
--- a/lib/psy.c
+++ b/lib/psy.c
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: psychoacoustics not including preecho
- last mod: $Id: psy.c,v 1.12 2000/01/22 13:28:27 xiphmont Exp $
+ last mod: $Id: psy.c,v 1.13 2000/01/28 09:05:14 xiphmont Exp $
 
  ********************************************************************/
 
@@ -43,9 +43,9 @@ static void set_curve(double *ref,double *c,int n, double crate){
   }
 }
 
-void _vp_psy_init(psy_lookup *p,vorbis_info_psy *vi,int n,long rate){
+void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){
   long i;
-  memset(p,0,sizeof(psy_lookup));
+  memset(p,0,sizeof(vorbis_look_psy));
   p->maskthresh=malloc(n*sizeof(double));
   p->barknum=malloc(n*sizeof(double));
   p->vi=vi;
@@ -74,18 +74,18 @@ void _vp_psy_init(psy_lookup *p,vorbis_info_psy *vi,int n,long rate){
 
 }
 
-void _vp_psy_clear(psy_lookup *p){
+void _vp_psy_clear(vorbis_look_psy *p){
   if(p){
     if(p->maskthresh)free(p->maskthresh);
     if(p->barknum)free(p->barknum);
-    memset(p,0,sizeof(psy_lookup));
+    memset(p,0,sizeof(vorbis_look_psy));
   }
 }
 
 /* Masking curve: linear rolloff on a Bark/dB scale, attenuated by
    maskthresh */
 /* right now, floor==mask */
-void _vp_mask_floor(psy_lookup *p,double *f, double *mask,double *floor){
+void _vp_mask_floor(vorbis_look_psy *p,double *f, double *mask,double *floor){
   int n=p->n;
   double hroll=p->vi->hrolldB;
   double lroll=p->vi->lrolldB;
@@ -140,22 +140,3 @@ static void time_convolve(double *s,double *r,int n,int m){
   }
 }
 
-/* for duplicating the info struct */
-
-void *_vi_psy_dup(void *i){
-  vorbis_info_psy *source=i;
-  if(source){
-    vorbis_info_psy *d=malloc(sizeof(vorbis_info_psy));
-    memcpy(d,source,sizeof(vorbis_info_psy));
-    return(d);
-  }else
-    return(NULL);
-}
-
-void _vi_psy_free(void *i){
-  if(i){
-    memset(i,0,sizeof(vorbis_info_psy));
-    free(i);
-  }
-}
-
index 57841a7..f41e119 100644 (file)
--- a/lib/psy.h
+++ b/lib/psy.h
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: random psychoacoustics (not including preecho)
- last mod: $Id: psy.h,v 1.6 2000/01/22 13:28:28 xiphmont Exp $
+ last mod: $Id: psy.h,v 1.7 2000/01/28 09:05:15 xiphmont Exp $
 
  ********************************************************************/
 
@@ -26,16 +26,17 @@ typedef struct {
   double *maskthresh;
   double *barknum;
 
-} psy_lookup;
+} vorbis_look_psy;
 
-extern void   _vp_psy_init(psy_lookup *p,vorbis_info_psy *vi,int n,long rate);
-extern void   _vp_psy_clear(psy_lookup *p);
+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(void *i);
 
-extern void   _vp_mask_floor(psy_lookup *p,double *pcm,
+extern void   _vp_mask_floor(vorbis_look_psy *p,double *pcm,
                             double *mask,double *floor);
-
+extern void   _vp_quantize(vorbis_look_psy *p, double *pcm, double *mask, 
+                          double *floor,int *aux);
 #endif
 
 
index b515731..4e430f8 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: residue backend 0 implementation
- last mod: $Id: res0.c,v 1.1 2000/01/20 04:43:04 xiphmont Exp $
+ last mod: $Id: res0.c,v 1.2 2000/01/28 09:05:16 xiphmont Exp $
 
  ********************************************************************/
 
 #include "vorbis/codec.h"
 #include "bitwise.h"
 #include "registry.h"
-#include "res0.h"
 
 /* unfinished as of 20000118 */
-extern _vi_info_res *_vorbis_res0_dup(_vi_info_res *source){
-  vorbis_info_res0 *d=malloc(sizeof(vorbis_info_res0));
-  memcpy(d,source,sizeof(vorbis_info_res0));
-  d->books=malloc(sizeof(int)*d->stages);
-  memcpy(d->books,((vorbis_info_res0 *)source)->books,
-        sizeof(int)*d->stages);
-  return(d); 
-}
 
-extern void _vorbis_res0_free(_vi_info_res *i){
-  vorbis_info_res0 *d=(vorbis_info_res0 *)i;
+void free_info(vorbis_info_residue *i){
+  vorbis_info_residue0 *d=(vorbis_info_residue0 *)i;
   if(d){
     if(d->books)free(d->books);
-    memset(d,0,sizeof(vorbis_info_res0));
+    memset(d,0,sizeof(vorbis_info_residue0));
     free(d);
   }
 }
 
+void free_look(vorbis_look_residue *i){
+}
+
 /* not yet */
-extern void _vorbis_res0_pack(oggpack_buffer *opb, _vi_info_res *vi){
+void pack(vorbis_info_residue *vr,oggpack_buffer *opb){
+}
+
+/* vorbis_info is for range checking */
+vorbis_info_residue *unpack(vorbis_info *vi,oggpack_buffer *opb){
 }
 
-extern _vi_info_res *_vorbis_res0_unpack(vorbis_info *vi,
-                                        oggpack_buffer *opb){
-  vorbis_info_res0 d;
-  memset(&d,0,sizeof(d));
-  return(_vorbis_res0_dup(&d));
+vorbis_look_residue *look (vorbis_info *vi,vorbis_info_mode *vm,
+                         vorbis_info_residue *vr){
 }
+
+int forward(vorbis_block *vb,vorbis_look_residue *l,double **in,int **aux,int ch){
+}
+int inverse(vorbis_block *vb,vorbis_look_residue *l,double **in,int ch){
+}
+
+vorbis_func_residue residue0_exportbundle={
+  &pack,
+  &unpack,
+  &look,
+  &free_info,
+  &free_look,
+  &forward,
+  &inverse
+};
diff --git a/lib/spectrum.c b/lib/spectrum.c
deleted file mode 100644 (file)
index 925c869..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/********************************************************************
- *                                                                  *
- * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
- * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
- * PLEASE READ THESE TERMS DISTRIBUTING.                            *
- *                                                                  *
- * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
- * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
- * http://www.xiph.org/                                             *
- *                                                                  *
- ********************************************************************
-
- function: spectrum envelope and residue code/decode
- last mod: $Id: spectrum.c,v 1.10 2000/01/05 03:11:03 xiphmont Exp $
-
- ********************************************************************/
-
-#include <stdio.h>
-#include <math.h>
-#include "vorbis/codec.h"
-
-#include "os.h"
-#include "bitwise.h"
-#include "spectrum.h"
-
-/* this code is still seriously abbreviated.  I'm filling in pieces as
-   we go... --Monty 19991004 */
-
-/* unlike other LPC-based coders, we never apply the filter but only
-   inspect the frequency response, thus we don't need to guard against
-   instability.  However, two coefficients quantising to the same
-   value will cause the response to explode.  */
-
-int _vs_spectrum_encode(vorbis_block *vb,double amp,double *lsp){
-  /* no real coding yet.  Just write out full sized words for now
-     because people need bitstreams to work with */
-
-  int scale=vb->W;
-  int m=vb->vd->vi->floororder[scale];
-  int n=vb->pcmend*64;
-  int last=0;
-  double dlast=0.;
-  double min=M_PI/n/2.;
-  
-  int bits=rint(log(n)/log(2));
-  int i;
-
-#ifdef TRAIN
-  if(amp>0){
-    FILE *out;
-    if(vb->W)
-      out=fopen("lspcoeff-long.vqd","a");
-    else
-      out=fopen("lspcoeff-short.vqd","a");
-
-    for(i=0;i<m;i++)
-      fprintf(out,"%lf ",lsp[i]);
-    fprintf(out,"\n");
-    fclose(out);
-
-    if(vb->W)
-      out=fopen("lspamp-long.vqd","a");
-    else
-      out=fopen("lspamp-short.vqd","a");
-    fprintf(out,"%lf\n",amp);
-    fclose(out);
-  }
-#endif
-  _oggpack_write(&vb->opb,amp*32768,18);
-  
-  for(i=0;i<m;i++){
-    int val=rint(lsp[i]/M_PI*n-last);
-    _oggpack_write(&vb->opb,val,bits);
-
-    lsp[i]=(last+=val)*M_PI/n;
-
-    /* Underpowered but sufficient for now. In the real spec (coming
-       soon), a distance of zero can't happen. */
-    if(lsp[i]<dlast+min)lsp[i]=dlast+min;
-    dlast=lsp[i];
-  }
-  return(0);
-}
-
-int _vs_spectrum_decode(vorbis_block *vb,double *amp,double *lsp){
-  int scale=vb->W;
-  int m=vb->vd->vi->floororder[scale];
-  int n=vb->pcmend*64;
-  int last=0;
-  double dlast=0.;
-  int bits=rint(log(n)/log(2));
-  int i;
-  double min=M_PI/n/2.;
-
-  *amp=_oggpack_read(&vb->opb,18)/32768.;
-
-  for(i=0;i<m;i++){
-    int val=_oggpack_read(&vb->opb,bits);
-    lsp[i]=(last+=val)*M_PI/n;
-
-    /* Underpowered but sufficient */
-    if(lsp[i]<dlast+min)lsp[i]=dlast+min;
-    dlast=lsp[i];
-  }
-  return(0);
-}
-
-void _vs_residue_train(vorbis_block *vb,double *data,double *curve,int n){
-  int i;
-  FILE *out;
-  if(vb->W)
-    out=fopen("residue-long.vqd","a");
-  else
-    out=fopen("residue-short.vqd","a");
-      
-  for(i=0;i<n;i++){
-    double val=0;
-    if(curve[i]!=0.)val=data[i]/curve[i];
-    fprintf(out,"%lf ",val);
-  }
-  fprintf(out,"\n");
-  fclose(out);
-} 
-
-void _vs_residue_quantize(double *data,double *curve,
-                                vorbis_info *vi,int n){
-
-  /* The following is temporary, hardwired bullshit */
-  int i;
-
-  for(i=0;i<n;i++){
-    int val=0;
-
-    if(curve[i]!=0.)val=rint(data[i]/curve[i]);
-    if(val>31)val=31;
-    if(val<-31)val=-31;
-
-
-    /*if(val==0){
-      if(data[i]<0){
-       val=-1;
-      }else{
-       val=1;
-      }
-      }*/
-    
-    data[i]=val;
-
-  }
-}
-
-int _vs_residue_encode(vorbis_block *vb,double *data){
-  /* no real coding yet.  Just write out full sized words for now
-     because people need bitstreams to work with */
-
-  int              n=vb->pcmend/2;
-  int i;
-
-  for(i=0;i<n;i++){
-    _oggpack_write(&vb->opb,(int)(data[i]+31),6);
-  }
-
-  return(0);
-}
-
-int _vs_residue_decode(vorbis_block *vb,double *data){
-  /* no real coding yet.  Just write out full sized words for now
-     because people need bitstreams to work with */
-
-  int              n=vb->pcmend/2;
-  int i;
-
-  for(i=0;i<n;i++){
-    data[i]=_oggpack_read(&vb->opb,6)-31;
-    /*if(data[i]>=0)data[i]+=1;*/
-  }
-  return(0);
-}
-
index a38b357..5f812d6 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.13 2000/01/10 14:06:31 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.14 2000/01/28 09:05:18 xiphmont Exp $
 
  ********************************************************************/
 
@@ -197,7 +197,8 @@ static void _bisect_forward_serialno(OggVorbis_File *vf,
 
 /* uses the local ogg_stream storage in vf; this is important for
    non-streaming input sources */
-static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,long *serialno){
+static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
+                         long *serialno){
   ogg_page og;
   ogg_packet op;
   int i,ret;
@@ -214,8 +215,8 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,long *serialno){
   /* extract the initial header from the first page and verify that the
      Ogg bitstream is in fact Vorbis data */
   
-  vorbis_info_clear(vi);
   vorbis_info_init(vi);
+  vorbis_comment_init(vc);
   
   i=0;
   while(i<3){
@@ -227,7 +228,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,long *serialno){
        fprintf(stderr,"Corrupt header in logical bitstream.\n");
        goto bail_header;
       }
-      if(vorbis_info_headerin(vi,&op)){
+      if(vorbis_synthesis_headerin(vi,vc,&op)){
        fprintf(stderr,"Illegal header in logical bitstream.\n");
        goto bail_header;
       }
@@ -244,6 +245,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,long *serialno){
 
  bail_header:
   vorbis_info_clear(vi);
+  vorbis_comment_clear(vc);
   ogg_stream_clear(&vf->os);
   return -1;
 }
@@ -252,7 +254,8 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,long *serialno){
    vorbis_info structs and PCM positions.  Only called by the seekable
    initialization (local stream storage is hacked slightly; pay
    attention to how that's done) */
-static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first,
+static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
+                                 vorbis_comment *first_c,
                                  long dataoffset){
   ogg_page og;
   int i,ret;
@@ -263,19 +266,18 @@ static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first,
   vf->serialnos=malloc(vf->links*sizeof(long));
   
   for(i=0;i<vf->links;i++){
-    if(first && i==0){
+    if(first_i && first_c && i==0){
       /* we already grabbed the initial header earlier.  This just
          saves the waste of grabbing it again */
-      memcpy(vf->vi+i,first,sizeof(vorbis_info));
-      memset(first,0,sizeof(vorbis_info));
+      memcpy(vf->vi+i,first_i,sizeof(vorbis_info));
+      memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
       vf->dataoffsets[i]=dataoffset;
     }else{
 
       /* seek to the location of the initial header */
 
       _seek_helper(vf,vf->offsets[i]);
-      if(_fetch_headers(vf,vf->vi+i,NULL)==-1){
-       vorbis_info_clear(vf->vi+i);
+      if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL)==-1){
        fprintf(stderr,"Error opening logical bitstream #%d.\n\n",i+1);
     
        ogg_stream_clear(&vf->os); /* clear local storage.  This is not
@@ -301,6 +303,7 @@ static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first,
          fprintf(stderr,"Could not find last page of logical "
                  "bitstream #%d\n\n",i);
          vorbis_info_clear(vf->vi+i);
+         vorbis_comment_clear(vf->vc+i);
          break;
        }
        if(ogg_page_frameno(&og)!=-1){
@@ -314,15 +317,17 @@ static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first,
 }
 
 static int _open_seekable(OggVorbis_File *vf){
-  vorbis_info initial;
+  vorbis_info initial_i;
+  vorbis_comment initial_c;
   long serialno,end;
   int ret;
   long dataoffset;
   ogg_page og;
   
   /* is this even vorbis...? */
-  memset(&initial,0,sizeof(vorbis_info));
-  ret=_fetch_headers(vf,&initial,&serialno);
+  vorbis_info_init(&initial_i);
+  vorbis_comment_init(&initial_c);
+  ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno);
   dataoffset=vf->offset;
   ogg_stream_clear(&vf->os);
   if(ret==-1)return(-1);
@@ -350,7 +355,7 @@ static int _open_seekable(OggVorbis_File *vf){
 
   }
 
-  _prefetch_all_headers(vf,&initial,dataoffset);
+  _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
   ov_raw_seek(vf,0);
 
   return(0);
@@ -362,7 +367,7 @@ static int _open_nonseekable(OggVorbis_File *vf){
   vf->vi=malloc(sizeof(vorbis_info));
 
   /* Try to fetch the headers, maintaining all the storage */
-  if(_fetch_headers(vf,vf->vi,&vf->current_serialno)==-1)return(-1);
+  if(_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno)==-1)return(-1);
     
   return 0;
 }
@@ -477,7 +482,7 @@ static int _process_packet(OggVorbis_File *vf,int readp){
        /* we're streaming */
        /* fetch the three header packets, build the info struct */
        
-       _fetch_headers(vf,vf->vi,&vf->current_serialno);
+       _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno);
        vf->current_link++;
        link=0;
       }
@@ -505,8 +510,10 @@ int ov_clear(OggVorbis_File *vf){
     
     if(vf->vi && vf->links){
       int i;
-      for(i=0;i<vf->links;i++)
+      for(i=0;i<vf->links;i++){
        vorbis_info_clear(vf->vi+i);
+       vorbis_comment_clear(vf->vc+i);
+      }
       free(vf->vi);
     }
     if(vf->dataoffsets)free(vf->dataoffsets);
@@ -919,6 +926,27 @@ vorbis_info *ov_info(OggVorbis_File *vf,int link){
   }
 }
 
+/* grr, strong typing, grr, no templates/inheritence, grr */
+vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
+  if(vf->seekable){
+    if(link<0)
+      if(vf->decode_ready)
+       return vf->vc+vf->current_link;
+      else
+       return NULL;
+    else
+      if(link>=vf->links)
+       return NULL;
+      else
+       return vf->vc+link;
+  }else{
+    if(vf->decode_ready)
+      return vf->vc;
+    else
+      return NULL;
+  }
+}
+
 /* up to this point, everything could more or less hide the multiple
    logical bitstream nature of chaining from the toplevel application
    if the toplevel application didn't particularly care.  However, at
index 65c75c7..db1b9b4 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: utility functions for loading .vqh and .vqd files
- last mod: $Id: bookutil.c,v 1.6 2000/01/21 13:42:35 xiphmont Exp $
+ last mod: $Id: bookutil.c,v 1.7 2000/01/28 09:05:19 xiphmont Exp $
 
  ********************************************************************/
 
@@ -26,7 +26,7 @@
 
 void codebook_unquantize(codebook *b){
   long j,k;
-  static_codebook *c=b->c;
+  const static_codebook *c=b->c;
   double mindel=float24_unpack(c->q_min);
   double delta=float24_unpack(c->q_delta);
   if(!b->valuelist)b->valuelist=malloc(sizeof(double)*c->entries*c->dim);
@@ -136,7 +136,7 @@ void reset_next_value(void){
 
 int get_vector(codebook *b,FILE *in,int start, int n,double *a){
   int i;
-  static_codebook *c=b->c;
+  const static_codebook *c=b->c;
 
   while(1){
 
@@ -188,7 +188,7 @@ char *find_seek_to(FILE *in,char *s){
 
 codebook *codebook_load(char *filename){
   codebook *b=calloc(1,sizeof(codebook));
-  static_codebook *c=b->c=calloc(1,sizeof(static_codebook));
+  static_codebook *c=(static_codebook *)(b->c=calloc(1,sizeof(static_codebook)));
   encode_aux *a=calloc(1,sizeof(encode_aux));
   FILE *in=fopen(filename,"r");
   char *line;
@@ -298,7 +298,7 @@ codebook *codebook_load(char *filename){
 }
 
 int codebook_entry(codebook *b,double *val){
-  static_codebook *c=b->c;
+  const static_codebook *c=b->c;
   encode_aux *t=c->encode_tree;
   int ptr=0,k;
   double *n=alloca(c->dim*sizeof(double));
index be063f8..a8c6204 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: function calls to collect codebook metrics
- last mod: $Id: metrics.c,v 1.4 2000/01/21 13:42:38 xiphmont Exp $
+ last mod: $Id: metrics.c,v 1.5 2000/01/28 09:05:20 xiphmont Exp $
 
  ********************************************************************/
 
@@ -66,7 +66,7 @@ void process_preprocess(codebook **bs,char *basename){
   }
 
   if(books){
-    static_codebook *b=bs[books-1]->c;
+    const static_codebook *b=bs[books-1]->c;
     histogram=calloc(b->entries,sizeof(double));
     histogram_distance=calloc(b->entries,sizeof(double));
     histogram_errorsq=calloc(b->entries*dim,sizeof(double));
index 41a822e..a3409cf 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: build a VQ codebook and the encoding decision 'tree'
- last mod: $Id: vqsplit.c,v 1.13 2000/01/21 13:42:41 xiphmont Exp $
+ last mod: $Id: vqsplit.c,v 1.14 2000/01/28 09:05:21 xiphmont Exp $
 
  ********************************************************************/
 
@@ -392,7 +392,7 @@ void vqsp_book(vqgen *v, codebook *b, long *quantlist){
   long *entryindex=malloc(sizeof(long)*v->entries);
   long *pointindex=malloc(sizeof(long)*v->points);
   long i,j;
-  static_codebook *c=b->c;
+  static_codebook *c=(static_codebook *)b->c;
   encode_aux *t;
 
   memset(b,0,sizeof(codebook));