[xiph-cvs] cvs commit: vorbis/vq bookutil.c distribution.c huffbuild.c latticehint.c

Monty xiphmont at xiph.org
Sat May 26 23:44:09 PDT 2001



xiphmont    01/05/26 23:44:08

  Modified:    examples seeking_example.c
               include/vorbis codec.h vorbisfile.h
               lib      Makefile.am analysis.c backends.h barkmel.c block.c
                        codebook.c codebook.h envelope.c floor0.c info.c
                        mapping0.c masking.h psy.c psy.h psytune.c
                        registry.c registry.h res0.c scales.h synthesis.c
                        vorbisenc.c vorbisfile.c
               lib/modes mode_A.h mode_AA.h mode_B.h mode_C.h mode_D.h
                        mode_E.h
               vq       bookutil.c distribution.c huffbuild.c latticehint.c
  Added:       lib      floor1.c
  Log:
  Floor 1
  Res 1
  Vorbisfile fixes/opts
  
  now all on mainline

Revision  Changes    Path
1.8       +145 -12   vorbis/examples/seeking_example.c

Index: seeking_example.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/examples/seeking_example.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- seeking_example.c	2001/02/26 03:50:38	1.7
+++ seeking_example.c	2001/05/27 06:43:58	1.8
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: illustrate seeking, and test it too
- last mod: $Id: seeking_example.c,v 1.7 2001/02/26 03:50:38 xiphmont Exp $
+ last mod: $Id: seeking_example.c,v 1.8 2001/05/27 06:43:58 xiphmont Exp $
 
  ********************************************************************/
 
@@ -21,28 +21,161 @@
 #include "vorbis/vorbisfile.h"
 #include "../lib/misc.h"
 
+
+void _verify(OggVorbis_File *ov,ogg_int64_t pos,
+	     ogg_int64_t val,ogg_int64_t pcmval,
+	     ogg_int64_t pcmlength,
+	     char *bigassbuffer){
+  int j;
+  long bread;
+  char buffer[4096];
+  int dummy;
+
+  /* verify the raw position, the pcm position and position decode */
+  if(val!=-1 && ov_raw_tell(ov)<val){
+    printf("raw position out of tolerance: requested %ld, got %ld\n",
+	   (long)val,(long)ov_raw_tell(ov));
+    exit(1);
+  }
+  if(pcmval!=-1 && ov_pcm_tell(ov)>pcmval){
+    printf("pcm position out of tolerance: requested %ld, got %ld\n",
+	   (long)pcmval,(long)ov_pcm_tell(ov));
+    exit(1);
+  }
+  pos=ov_pcm_tell(ov);
+  if(pos<0 || pos>pcmlength){
+    printf("pcm position out of bounds: got %ld\n",(long)pos);
+    exit(1);
+  }
+  bread=ov_read(ov,buffer,4096,1,1,1,&dummy);
+  for(j=0;j<bread;j++){
+    if(buffer[j]!=bigassbuffer[j+pos*2]){
+      printf("data position after seek doesn't match pcm position\n");
+      exit(1);
+    }
+  }
+}
+
 int main(){
   OggVorbis_File ov;
-  int i;
+  int i,ret;
+  ogg_int64_t pcmlength;
+  char *bigassbuffer;
+  int dummy;
 
   /* open the file/pipe on stdin */
   if(ov_open(stdin,&ov,NULL,-1)<0){
     printf("Could not open input as an OggVorbis file.\n\n");
     exit(1);
   }
-  
-  /* print details about each logical bitstream in the input */
+
   if(ov_seekable(&ov)){
-    double length=ov_time_total(&ov,-1);
-    printf("testing seeking to random places in %g seconds....\n",length);
-    for(i=0;i<100;i++){
-      double val=(double)rand()/RAND_MAX*length;
-      ov_time_seek(&ov,val);
-      printf("\r\t%d [%gs]...     ",i,val);
-      fflush(stdout);
+
+    /* to simplify our own lives, we want to assume the whole file is
+       stereo.  Verify this to avoid potentially mystifying users
+       (pissing them off is OK, just don't confuse them) */
+    for(i=0;i<ov.links;i++){
+      vorbis_info *vi=ov_info(&ov,i);
+      if(vi->channels!=2){
+	printf("Sorry; right now seeking_test can only use Vorbis files\n"
+	       "that are entirely stereo.\n\n");
+	exit(1);
+      }
+    }
+    
+    /* because we want to do sample-level verification that the seek
+       does what it claimed, decode the entire file into memory */
+    printf("loading....\n");
+    fflush(stdout);
+    pcmlength=ov_pcm_total(&ov,-1);
+    bigassbuffer=malloc(pcmlength*2); /* w00t */
+    i=0;
+    while(i<pcmlength*2){
+      int ret=ov_read(&ov,bigassbuffer+i,pcmlength*2-i,1,1,1,&dummy);
+      if(ret<0)continue;
+      if(ret){
+	i+=ret;
+      }else{
+	pcmlength=i/2;
+      }
+    }
+    
+    /* Exercise all the real seeking cases; ov_raw_seek,
+       ov_pcm_seek_page and ov_pcm_seek.  time seek is just a wrapper
+       on pcm_seek */
+    {
+      ogg_int64_t length=ov.end;
+      printf("testing raw seeking to random places in %ld bytes....\n",
+	     (long)length);
+    
+      for(i=0;i<1000;i++){
+	ogg_int64_t val=(double)rand()/RAND_MAX*length;
+	ogg_int64_t pos;
+	printf("\r\t%d [raw position %ld]...     ",i,(long)val);
+	fflush(stdout);
+	ret=ov_raw_seek(&ov,val);
+	if(ret<0){
+	  printf("seek failed: %d\n",ret);
+	  exit(1);
+	}
+
+	_verify(&ov,pos,val,-1,pcmlength,bigassbuffer);
+
+      }
+    }
+
+    printf("\r");
+    {
+      ogg_int64_t length=ov.end;
+      printf("testing pcm page seeking to random places in %ld samples....\n",
+	     (long)pcmlength);
+    
+      for(i=0;i<1000;i++){
+	ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
+	ogg_int64_t pos;
+	printf("\r\t%d [pcm position %ld]...     ",i,(long)val);
+	fflush(stdout);
+	ret=ov_pcm_seek_page(&ov,val);
+	if(ret<0){
+	  printf("seek failed: %d\n",ret);
+	  exit(1);
+	}
+
+	_verify(&ov,pos,-1,val,pcmlength,bigassbuffer);
+
+      }
+    }
+    
+    printf("\r");
+    {
+      ogg_int64_t length=ov.end;
+      printf("testing pcm exact seeking to random places in %ld samples....\n",
+	     (long)pcmlength);
+    
+      for(i=0;i<1000;i++){
+	ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
+	ogg_int64_t pos;
+	printf("\r\t%d [pcm position %ld]...     ",i,(long)val);
+	fflush(stdout);
+	ret=ov_pcm_seek(&ov,val);
+	if(ret<0){
+	  printf("seek failed: %d\n",ret);
+	  exit(1);
+	}
+	if(ov_pcm_tell(&ov)!=val){
+	  printf("Decalred position didn't perfectly match request: %ld != %ld\n",
+		 (long)val,(long)ov_pcm_tell(&ov));
+	  exit(1);
+	}
+
+	_verify(&ov,pos,-1,val,pcmlength,bigassbuffer);
+
+      }
     }
     
-    printf("\r                                   \nOK.\n\n");
+    printf("\r                                           \nOK.\n\n");
+
+
   }else{
     printf("Standard input was not seekable.\n");
   }

1.38      +2 -1      vorbis/include/vorbis/codec.h

Index: codec.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/include/vorbis/codec.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- codec.h	2001/02/26 03:50:39	1.37
+++ codec.h	2001/05/27 06:43:59	1.38
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: libvorbis codec headers
- last mod: $Id: codec.h,v 1.37 2001/02/26 03:50:39 xiphmont Exp $
+ last mod: $Id: codec.h,v 1.38 2001/05/27 06:43:59 xiphmont Exp $
 
  ********************************************************************/
 
@@ -199,6 +199,7 @@
 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);
+extern long     vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
 
 /* Vorbis ERRORS and return codes ***********************************/
 

1.14      +22 -12    vorbis/include/vorbis/vorbisfile.h

Index: vorbisfile.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/include/vorbis/vorbisfile.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- vorbisfile.h	2001/02/26 03:50:39	1.13
+++ vorbisfile.h	2001/05/27 06:43:59	1.14
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.h,v 1.13 2001/02/26 03:50:39 xiphmont Exp $
+ last mod: $Id: vorbisfile.h,v 1.14 2001/05/27 06:43:59 xiphmont Exp $
 
  ********************************************************************/
 
@@ -43,27 +43,32 @@
   long   (*tell_func)  (void *datasource);
 } ov_callbacks;
 
+#define  NOTOPEN   0
+#define  PARTOPEN  1
+#define  OPENED    2
+#define  STREAMSET 3
+#define  INITSET   4
 
 typedef struct OggVorbis_File {
-  void             *datasource; /* Pointer to a FILE *, etc. */
+  void            *datasource; /* Pointer to a FILE *, etc. */
   int              seekable;
-  ogg_int64_t          offset;
-  ogg_int64_t          end;
+  ogg_int64_t      offset;
+  ogg_int64_t      end;
   ogg_sync_state   oy; 
 
   /* If the FILE handle isn't seekable (eg, a pipe), only the current
      stream appears */
   int              links;
-  ogg_int64_t          *offsets;
-  ogg_int64_t          *dataoffsets;
-  long             *serialnos;
-  ogg_int64_t          *pcmlengths;
-  vorbis_info      *vi;
-  vorbis_comment   *vc;
+  ogg_int64_t     *offsets;
+  ogg_int64_t     *dataoffsets;
+  long            *serialnos;
+  ogg_int64_t     *pcmlengths;
+  vorbis_info     *vi;
+  vorbis_comment  *vc;
 
   /* Decoding working state local storage */
-  ogg_int64_t          pcm_offset;
-  int              decode_ready;
+  ogg_int64_t      pcm_offset;
+  int              ready_state;
   long             current_serialno;
   int              current_link;
 
@@ -83,6 +88,11 @@
 extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
 extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
                 char *initial, long ibytes, ov_callbacks callbacks);
+
+extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
+extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf,
+		char *initial, long ibytes, ov_callbacks callbacks);
+extern int ov_test_open(OggVorbis_File *vf);
 
 extern long ov_bitrate(OggVorbis_File *vf,int i);
 extern long ov_bitrate_instant(OggVorbis_File *vf);

1.12      +3 -2      vorbis/lib/Makefile.am

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/Makefile.am,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Makefile.am	2001/02/19 07:48:39	1.11
+++ Makefile.am	2001/05/27 06:43:59	1.12
@@ -8,8 +8,9 @@
 
 lib_LTLIBRARIES = libvorbis.la libvorbisfile.la libvorbisenc.la
 
-libvorbis_la_SOURCES = mdct.c smallft.c block.c envelope.c window.c lsp.c lpc.c\
-			analysis.c synthesis.c psy.c info.c time0.c floor0.c\
+libvorbis_la_SOURCES = mdct.c smallft.c block.c envelope.c window.c lsp.c \
+			lpc.c analysis.c synthesis.c psy.c info.c time0.c \
+			floor1.c floor0.c\
                         res0.c mapping0.c registry.c codebook.c sharedbook.c\
                         lookup.c bitbuffer.c\
                         envelope.h lpc.h lsp.h codebook.h misc.h psy.h\

1.44      +30 -22    vorbis/lib/analysis.c

Index: analysis.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/analysis.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- analysis.c	2001/02/26 03:50:41	1.43
+++ analysis.c	2001/05/27 06:43:59	1.44
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: single-block PCM analysis mode dispatch
- last mod: $Id: analysis.c,v 1.43 2001/02/26 03:50:41 xiphmont Exp $
+ last mod: $Id: analysis.c,v 1.44 2001/05/27 06:43:59 xiphmont Exp $
 
  ********************************************************************/
 
@@ -75,32 +75,40 @@
 }
 
 /* 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
+void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB){
   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]);
+  //  if(i==5870){
+    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(v+j));
+	}else{
+	  fprintf(of,"%g\n",v[j]);
+	}
       }
     }
-  }
-  fclose(of);
+    fclose(of);
+    //  }
+}
+
+void _analysis_output(char *base,int i,float *v,int n,int bark,int dB){
+#ifdef ANALYSIS
+  _analysis_output_always(base,i,v,n,bark,dB);
 #endif
 }
+

1.7       +35 -2     vorbis/lib/backends.h

Index: backends.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/backends.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- backends.h	2001/02/26 03:50:41	1.6
+++ backends.h	2001/05/27 06:43:59	1.7
@@ -12,7 +12,7 @@
 
  function: libvorbis backend and mapping structures; needed for 
            static mode headers
- last mod: $Id: backends.h,v 1.6 2001/02/26 03:50:41 xiphmont Exp $
+ last mod: $Id: backends.h,v 1.7 2001/05/27 06:43:59 xiphmont Exp $
 
  ********************************************************************/
 
@@ -61,7 +61,9 @@
   void (*free_info) (vorbis_info_floor *);
   void (*free_look) (vorbis_look_floor *);
   int  (*forward)   (struct vorbis_block *,vorbis_look_floor *,
-		     float *);
+		     const float *, const float *, /* in */
+		     const float *, const float *, /* in */
+		     float *, float *);            /* out */
   int  (*inverse)   (struct vorbis_block *,vorbis_look_floor *,
                      float *);
 } vorbis_func_floor;
@@ -81,6 +83,37 @@
   float greaterthan;  /* encode-only config setting hacks for libvorbis */
 
 } vorbis_info_floor0;
+
+#define VIF_POSIT 63
+#define VIF_CLASS 16
+#define VIF_PARTS 31
+typedef struct{
+  int   partitions;                /* 0 to 31 */
+  int   partitionclass[VIF_PARTS]; /* 0 to 15 */
+
+  int   class_dim[VIF_CLASS];        /* 1 to 8 */
+  int   class_subs[VIF_CLASS];       /* 0,1,2,3 (bits: 1<<n poss) */
+  int   class_book[VIF_CLASS];       /* subs ^ dim entries */
+  int   class_subbook[VIF_CLASS][8]; /* [VIF_CLASS][subs] */
+
+
+  int   mult;                      /* 1 2 3 or 4 */ 
+  int   postlist[VIF_POSIT+2];    /* first two implicit */ 
+
+
+  /* encode side analysis parameters */
+  float maxover;     
+  float maxunder;  
+  float maxerr;    
+
+  int   twofitminsize;
+  int   twofitminused;
+  int   twofitweight;  
+  float twofitatten;
+  int   unusedminsize;
+  int   unusedmin_n;
+
+} vorbis_info_floor1;
 
 /* Residue backend generic *****************************************/
 typedef struct{

1.6       +8 -4      vorbis/lib/barkmel.c

Index: barkmel.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/barkmel.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- barkmel.c	2001/02/26 03:50:41	1.5
+++ barkmel.c	2001/05/27 06:43:59	1.6
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: bark scale utility
- last mod: $Id: barkmel.c,v 1.5 2001/02/26 03:50:41 xiphmont Exp $
+ last mod: $Id: barkmel.c,v 1.6 2001/05/27 06:43:59 xiphmont Exp $
 
  ********************************************************************/
 
@@ -51,9 +51,13 @@
 
 
   }
-  for(i=0;i<28;i++){
-    fprintf(stderr,"bark=%d %gHz\n",
-	    i,fromBARK(i));
+  {
+    float i;
+    int j;
+    for(i=0.,j=0;i<28;i+=2.107,j++){
+      fprintf(stderr,"(%d) bark=%f %gHz (%d of 128)\n",
+	      j,i,fromBARK(i),(int)(fromBARK(i)/22050.*128.));
+    }
   }
   return(0);
 }

1.48      +2 -2      vorbis/lib/block.c

Index: block.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/block.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- block.c	2001/03/26 23:27:42	1.47
+++ block.c	2001/05/27 06:43:59	1.48
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.47 2001/03/26 23:27:42 xiphmont Exp $
+ last mod: $Id: block.c,v 1.48 2001/05/27 06:43:59 xiphmont Exp $
 
  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
  more amusing by Vorbis' current two allowed block sizes.
@@ -787,7 +787,7 @@
 /* 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(v->pcm_returned>-1 && v->pcm_returned<v->centerW){
     if(pcm){
       int i;
       for(i=0;i<vi->channels;i++)

1.24      +39 -2     vorbis/lib/codebook.c

Index: codebook.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/codebook.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- codebook.c	2001/02/26 03:50:41	1.23
+++ codebook.c	2001/05/27 06:43:59	1.24
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: basic codebook pack/unpack/code/decode operations
- last mod: $Id: codebook.c,v 1.23 2001/02/26 03:50:41 xiphmont Exp $
+ last mod: $Id: codebook.c,v 1.24 2001/05/27 06:43:59 xiphmont Exp $
 
  ********************************************************************/
 
@@ -40,7 +40,7 @@
      length random.  Decide between the two now. */
   
   for(i=1;i<c->entries;i++)
-    if(c->lengthlist[i]<c->lengthlist[i-1])break;
+    if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break;
   if(i==c->entries)ordered=1;
   
   if(ordered){
@@ -411,6 +411,43 @@
     for(i=0,o=0;i<book->dim;i++,o+=step)
       for (j=0;j<step;j++)
        a[o+j]*=t[j][i];
+    break;
+  }
+  return(0);
+}
+
+long s_vorbis_book_decodev(codebook *book,float *a,oggpack_buffer *b,
+			   int partsize,int addmul){
+  int i,j,entry;
+  float *t;
+
+  switch(addmul){
+  case -1:
+    for(i=0;i<partsize;){
+      entry = vorbis_book_decode(book,b);
+      if(entry==-1)return(-1);
+      t     = book->valuelist+entry*book->dim;
+      for (j=0;j<book->dim;)
+	a[i++]=t[j++];
+    }
+    break;
+  case 0:
+    for(i=0;i<partsize;){
+      entry = vorbis_book_decode(book,b);
+      if(entry==-1)return(-1);
+      t     = book->valuelist+entry*book->dim;
+      for (j=0;j<book->dim;)
+	a[i++]+=t[j++];
+    }
+    break;
+  case 1:
+    for(i=0;i<partsize;){
+      entry = vorbis_book_decode(book,b);
+      if(entry==-1)return(-1);
+      t     = book->valuelist+entry*book->dim;
+      for (j=0;j<book->dim;)
+	a[i++]*=t[j++];
+    }
     break;
   }
   return(0);

1.6       +3 -1      vorbis/lib/codebook.h

Index: codebook.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/codebook.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- codebook.h	2001/02/26 03:50:41	1.5
+++ codebook.h	2001/05/27 06:43:59	1.6
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: basic shared codebook operations
- last mod: $Id: codebook.h,v 1.5 2001/02/26 03:50:41 xiphmont Exp $
+ last mod: $Id: codebook.h,v 1.6 2001/05/27 06:43:59 xiphmont Exp $
 
  ********************************************************************/
 
@@ -153,6 +153,8 @@
                                  int step,int stagetype);
 extern long s_vorbis_book_decodevs(codebook *book, float *a, oggpack_buffer *b,
                                    int step,int stagetype);
+extern long s_vorbis_book_decodev(codebook *book, float *a, oggpack_buffer *b,
+				   int partsize,int stagetype);
 
 
 

1.36      +3 -3      vorbis/lib/envelope.c

Index: envelope.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/envelope.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- envelope.c	2001/02/26 03:50:41	1.35
+++ envelope.c	2001/05/27 06:43:59	1.36
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: PCM data envelope analysis and manipulation
- last mod: $Id: envelope.c,v 1.35 2001/02/26 03:50:41 xiphmont Exp $
+ last mod: $Id: envelope.c,v 1.36 2001/05/27 06:43:59 xiphmont Exp $
 
  Preecho calculation.
 
@@ -141,8 +141,8 @@
     B+=post[i]*post[i];
   }
 
-  A=todB(A);
-  B=todB(B);
+  A=todB(&A);
+  B=todB(&B);
 
   return(B-A);
 }

1.40      +41 -20    vorbis/lib/floor0.c

Index: floor0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/floor0.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- floor0.c	2001/02/26 03:50:41	1.39
+++ floor0.c	2001/05/27 06:43:59	1.40
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: floor backend 0 implementation
- last mod: $Id: floor0.c,v 1.39 2001/02/26 03:50:41 xiphmont Exp $
+ last mod: $Id: floor0.c,v 1.40 2001/05/27 06:43:59 xiphmont Exp $
 
  ********************************************************************/
 
@@ -197,6 +197,7 @@
   float *work=alloca(sizeof(float)*mapped);
   int i,j,last=0;
   int bark=0;
+  static int seq=0;
 
   memset(work,0,sizeof(float)*mapped);
   
@@ -232,17 +233,30 @@
   /* 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];
+
+
+  /**********************/
+
+  for(i=0;i<l->n;i++)
+    curve[i]-=150;
+
+  _analysis_output("barkfloor",seq,work,bark,0,0);
+  _analysis_output("barkcurve",seq++,curve,l->n,1,0);
+
+  for(i=0;i<l->n;i++)
+    curve[i]+=150;
+
+  /**********************/
   
   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){
+static int floor0_forward(vorbis_block *vb,vorbis_look_floor *in,
+			  const float *mdct, const float *logmdct,   /* in */
+			  const float *logmask, const float *logmax, /* in */
+			  float *residue, float *codedflr){          /* out */
   long j;
-  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+  vorbis_look_floor0 *look=(vorbis_look_floor0 *)in;
   vorbis_info_floor0 *info=look->vi;
   float amp;
   long bits=0;
@@ -267,11 +281,11 @@
      positive, so we offset it. */
 
   for(j=0;j<look->n;j++)
-    flr[j]+=info->ampdB;
+    codedflr[j]=logmask[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=sqrt(_curve_to_lpc(codedflr,codedflr,look));
 
   /* amp is in the range (0. to ampdB].  Encode that range using
      ampbits bits */
@@ -292,8 +306,8 @@
 
   if(val){
     /* LSP <-> LPC is orthogonal and LSP quantizes more stably  */
-    _analysis_output("lpc",seq-1,flr,look->m,0,0);
-    if(vorbis_lpc_to_lsp(flr,flr,look->m))
+    _analysis_output("lpc",seq-1,codedflr,look->m,0,0);
+    if(vorbis_lpc_to_lsp(codedflr,codedflr,look->m))
       val=0;
 
   }
@@ -309,15 +323,15 @@
     codebook *b;
     int booknum;
 
-    _analysis_output("lsp",seq-1,flr,look->m,0,0);
+    _analysis_output("lsp",seq-1,codedflr,look->m,0,0);
 
     /* which codebook to use? We do it only by range right now. */
     if(info->numbooks>1){
       float last=0.;
       for(j=0;j<look->m;j++){
-	float val=flr[j]-last;
+	float val=codedflr[j]-last;
         if(val<info->lessthan || val>info->greaterthan)break;
-	last=flr[j];
+	last=codedflr[j];
       }
       if(j<look->m)
         booknum=0;
@@ -334,8 +348,8 @@
     {
       float last=0.f;
       for(j=0;j<look->m;j++){
-	fprintf(of,"%.12g, ",flr[j]-last);
-	last=flr[j];
+	fprintf(of,"%.12g, ",codedflr[j]-last);
+	last=codedflr[j];
       }
     }
     fprintf(of,"\n");
@@ -351,7 +365,7 @@
        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);
+      int entry=_f0_fit(b,codedflr,lspwork,j);
       bits+=vorbis_book_encode(b,entry,&vb->opb);
 
 #ifdef TRAIN_LSP
@@ -367,9 +381,16 @@
     _analysis_output("lsp2",seq-1,lspwork,look->m,0,0);
 
     /* take the coefficients back to a spectral envelope curve */
-    vorbis_lsp_to_curve(flr,look->linearmap,look->n,look->ln,
+    vorbis_lsp_to_curve(codedflr,look->linearmap,look->n,look->ln,
                         lspwork,look->m,amp,info->ampdB);
-    _analysis_output("lsp3",seq-1,flr,look->n,0,1);
+
+    _analysis_output("barklsp",seq-1,codedflr,look->n,1,1);
+    _analysis_output("lsp3",seq-1,codedflr,look->n,0,1);
+
+    /* generate residue output */
+    for(j=0;j<look->n;j++)
+      residue[j]=mdct[j]/codedflr[j];
+    
     return(val);
   }
 
@@ -377,7 +398,7 @@
     fclose(of);
 #endif
 
-  memset(flr,0,sizeof(float)*look->n);
+  memset(codedflr,0,sizeof(float)*look->n);
   return(val);
 }
 

1.40      +2 -2      vorbis/lib/info.c

Index: info.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/info.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- info.c	2001/02/26 03:50:41	1.39
+++ info.c	2001/05/27 06:44:00	1.40
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: maintain the info structure, info <-> header packets
- last mod: $Id: info.c,v 1.39 2001/02/26 03:50:41 xiphmont Exp $
+ last mod: $Id: info.c,v 1.40 2001/05/27 06:44:00 xiphmont Exp $
 
  ********************************************************************/
 
@@ -408,7 +408,7 @@
 }
 
 static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
-  char temp[]="Xiphophorus libVorbis I 20010225";
+  char temp[]="Xiphophorus libVorbis I 20010501";
 
   /* preamble */  
   oggpack_write(opb,0x03,8);

1.28      +45 -42    vorbis/lib/mapping0.c

Index: mapping0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/mapping0.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- mapping0.c	2001/02/26 13:31:31	1.27
+++ mapping0.c	2001/05/27 06:44:00	1.28
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.27 2001/02/26 13:31:31 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.28 2001/05/27 06:44:00 xiphmont Exp $
 
  ********************************************************************/
 
@@ -197,6 +197,7 @@
 #include "envelope.h"
 #include "mdct.h"
 #include "psy.h"
+#define VORBIS_IEEE_FLOAT32
 #include "scales.h"
 
 /* no time mapping implementation for now */
@@ -217,77 +218,80 @@
 
   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));
+  float *work=_vorbis_block_alloc(vb,n*sizeof(float));
   float newmax=vbi->ampmax;
 
   for(i=0;i<vi->channels;i++){
-    float *pcm=vb->pcm[i];
     float scale=4.f/n;
     int submap=info->chmuxlist[i];
     float ret;
 
-    _analysis_output("pcm",seq,pcm,n,0,0);
+    /* the following makes things clearer to *me* anyway */
+    float *pcm     =vb->pcm[i]; 
+    float *mdct    =pcm;
+    float *logmdct =pcm+n/2;
+    float *res     =pcm;
+    float *codedflr=pcm+n/2;
+    float *fft     =work;
+    float *logfft  =work;
+    float *logmax  =work;
+    float *logmask =work+n/2;
 
     /* window the PCM data */
     for(j=0;j<n;j++)
-      additional[j]=pcm[j]*=window[j];
-	    
-    _analysis_output("windowed",seq,pcm,n,0,0);
-
+      fft[j]=pcm[j]*=window[j];
+    
     /* transform the PCM data */
     /* only MDCT right now.... */
     mdct_forward(b->transform[vb->W][0],pcm,pcm);
+    for(j=0;j<n/2;j++)
+      logmdct[j]=todB(mdct+j);
     
     /* FFT yields more accurate tonal estimation (not phase sensitive) */
-    drft_forward(&look->fft_look,additional);
-    
-    additional[0]=fabs(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);
+    drft_forward(&look->fft_look,fft);
+    fft[0]*=scale;
+    fft[0]=todB(fft);
+    for(j=1;j<n-1;j+=2){
+      float temp=scale*FAST_HYPOT(fft[j],fft[j+1]);
+      logfft[(j+1)>>1]=todB(&temp);
+    }
 
+    _analysis_output("fft",seq,logfft,n/2,0,0);
+    _analysis_output("mdct",seq,logmdct,n/2,0,0);
+
     /* perform psychoacoustics; do masking */
-    ret=_vp_compute_mask(look->psy_look+submap,additional,additional+n/2,
-			 floor[i],NULL,vbi->ampmax);
+    ret=_vp_compute_mask(look->psy_look+submap,
+			 logfft, /* -> logmax */
+			 logmdct,
+			 logmask,
+			 vbi->ampmax);
     if(ret>newmax)newmax=ret;
 
-    _analysis_output("prefloor",seq,floor[i],n/2,0,0);
+    _analysis_output("mask",seq,logmask,n/2,0,0);
     
     /* perform floor encoding */
     nonzero[i]=look->floor_func[submap]->
-      forward(vb,look->floor_look[submap],floor[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]);
+      forward(vb,look->floor_look[submap],
+	      mdct,
+	      logmdct,
+	      logmask,
+	      logmax,
+	      res,
+	      codedflr);
 
-    _analysis_output("res",seq++,pcm,n/2,0,0);
+    _analysis_output("codedflr",seq,codedflr,n/2,0,1);
+    _analysis_output("res",seq++,res,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]);
-	if(fabs(pcm[i])>1000){
+      for(j=0;j<n/2;j++){
+	fprintf(of,"%.2f, ",res[j]);
+	if(fabs(res[j])>1000){
           fprintf(stderr," %d ",seq-1);
         }
       }
@@ -297,7 +301,6 @@
 #endif      
   }
 
-  seq++;
   vbi->ampmax=newmax;
 
   /* perform residue encoding with residue mapping; this is

1.14      +2 -2      vorbis/lib/masking.h

Index: masking.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/masking.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- masking.h	2001/02/26 03:50:42	1.13
+++ masking.h	2001/05/27 06:44:00	1.14
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: masking curve data for psychoacoustics
- last mod: $Id: masking.h,v 1.13 2001/02/26 03:50:42 xiphmont Exp $
+ last mod: $Id: masking.h,v 1.14 2001/05/27 06:44:00 xiphmont Exp $
 
  ********************************************************************/
 
@@ -22,7 +22,7 @@
 float ATH_Bark_dB[]={  
    15,   15,   15,    15,    11,    10,     8,    7,    7,    7,
     6,    2,    0,     0,    -3,    -5,    -6,   -6, -4.5f, 2.5f,
-   10,   15,   15,    15,    15,    15,   15};
+   10,   15,   20,    30,    40,    50,   60};
 
 /* The below masking curves are straight from the R. Ehmer
    (J. Acoustical Society of America) papers ca 1958-59.  I modified

1.45      +139 -128  vorbis/lib/psy.c

Index: psy.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/psy.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- psy.c	2001/03/21 07:44:46	1.44
+++ psy.c	2001/05/27 06:44:00	1.45
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: psychoacoustics not including preecho
- last mod: $Id: psy.c,v 1.44 2001/03/21 07:44:46 msmith Exp $
+ last mod: $Id: psy.c,v 1.45 2001/05/27 06:44:00 xiphmont Exp $
 
  ********************************************************************/
 
@@ -178,7 +178,7 @@
 }
 
 void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){
-  long i,j;
+  long i,j,lo=0,hi=0;
   long maxoc;
   memset(p,0,sizeof(vorbis_look_psy));
 
@@ -192,21 +192,31 @@
 
   p->ath=_ogg_malloc(n*sizeof(float));
   p->octave=_ogg_malloc(n*sizeof(long));
-  p->bark=_ogg_malloc(n*sizeof(float));
+  p->bark=_ogg_malloc(n*sizeof(unsigned long));
   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++){
+    float bark=toBARK(rate/(2*n)*i); 
+
+    for(;lo+vi->noisewindowlomin<i && 
+	  toBARK(rate/(2*n)*lo)<=(bark-vi->noisewindowlo);lo++);
+    
+    for(;hi<n && (hi<i+vi->noisewindowhimin ||
+	  toBARK(rate/(2*n)*hi)<=(bark+vi->noisewindowhi));hi++);
+    
+    p->bark[i]=((hi+1)<<16)+(lo+1);
 
+  }
+
   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->noisemedian=_ogg_malloc(n*sizeof(int));
   p->noiseoffset=_ogg_malloc(n*sizeof(float));
   p->peakatt=_ogg_malloc(P_BANDS*sizeof(float *));
   for(i=0;i<P_BANDS;i++){
@@ -296,12 +306,13 @@
     inthalfoc=(int)halfoc;
     del=halfoc-inthalfoc;
 
-    p->noisemedian[i]=
-      p->vi->noisemedian[inthalfoc*2]*(1.-del) + 
-      p->vi->noisemedian[inthalfoc*2+2]*del;
+    p->noisemedian[i]=rint(
+      (p->vi->noisemedian[inthalfoc*2]*(1.-del) + 
+       p->vi->noisemedian[inthalfoc*2+2]*del)*1024.f);
     p->noiseoffset[i]=
       p->vi->noisemedian[inthalfoc*2+1]*(1.-del) + 
-      p->vi->noisemedian[inthalfoc*2+3]*del;
+      p->vi->noisemedian[inthalfoc*2+3]*del -
+      140.f;
   }
   /*_analysis_output("mediancurve",0,p->noisemedian,n,0,0);*/
 }
@@ -331,21 +342,23 @@
 
 /* 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;
+		       const float **curves,
+		       float amp,
+		       int oc, int n,
+		       int linesper,float dBoffset){
+  int i,post1;
+  int seedptr;
+  const float *posts,*curve;
 
   int choice=(int)((amp+dBoffset)*.1f);
   choice=max(choice,0);
   choice=min(choice,P_LEVELS-1);
   posts=curves[choice];
   curve=posts+2;
+  post1=(int)posts[1];
   seedptr=oc+(posts[0]-16)*linesper-(linesper>>1);
 
-  for(i=posts[0];i<posts[1];i++){
+  for(i=posts[0];i<post1;i++){
     if(seedptr>0){
       float lin=amp+curve[i];
       if(seed[seedptr]<lin)seed[seedptr]=lin;
@@ -356,7 +369,7 @@
 }
 
 static void seed_peak(float *seed,
-		      float *att,
+		      const float *att,
                       float amp,
                       int oc,
                       int linesper,
@@ -374,10 +387,10 @@
 }
 
 static void seed_loop(vorbis_look_psy *p,
-		      float ***curves,
-		      float **att,
-		      float *f, 
-		      float *flr,
+		      const float ***curves,
+		      const float **att,
+		      const float *f, 
+		      const float *flr,
                       float *minseed,
                       float *maxseed,
                       float specmax){
@@ -531,75 +544,103 @@
   
 }
 
-/* quarter-dB bins */
-#define BIN(x)   ((int)((x)*negFour))
-#define BINdB(x) ((x)*negQuarter)
-#define BINCOUNT (200*4)
+/* set to match vorbis_quantdblook.h */
+#define BINCOUNT 280
 #define LASTBIN  (BINCOUNT-1)
 
-static void bark_noise_median(long n,float *b,float *f,float *noise,
+static int psy_dBquant(const float *x){
+  int i= *x*2.f+279.5f;
+  if(i>279)return(279);
+  if(i<0)return(0);
+  return i;
+}
+
+
+static void bark_noise_median(int n,const long *b,const float *f,
+			      float *noise,
                               float lowidth,float hiwidth,
                               int lomin,int himin,
-			      float *thresh,float *off){
-  long i=0,lo=0,hi=0;
-  float bi,threshi;
-  long median=LASTBIN;
-  float negFour = -4.0f;
-  float negQuarter = -0.25f;
-
-   /* these are really integral values, but we store them in floats to
-      avoid excessive float/int conversions, which GCC and MSVC are
-      farily poor at optimizing. */
-
-  float radix[BINCOUNT];
-  float countabove=0;
-  float countbelow=0;
-
-  memset(radix,0,sizeof(radix));
+			      const int *thresh,const float *off,
+			      int fixed){
+  int i=0,lo=-1,hi=-1,fixedc=0;
+  int  median=LASTBIN>>1;
+
+  int barkradix[BINCOUNT];
+  int barkcountbelow=0;
+
+  int fixedradix[BINCOUNT];
+  int fixedcountbelow=0;
+
+  memset(barkradix,0,sizeof(barkradix));
+  memset(fixedradix,0,sizeof(fixedradix));
+
+  /* bootstrap the fixed window case seperately */
+  for(i=0;i<(fixed>>1);i++){
+    int bin=psy_dBquant(f+i);
+    fixedradix[bin]++;
+    fixedc++;
+    if(bin<=median)
+      fixedcountbelow++;
+  }
 
   for(i=0;i<n;i++){
     /* find new lo/hi */
-    bi=b[i]+hiwidth;
-    for(;hi<n && (hi<i+himin || b[hi]<=bi);hi++){
-      int bin=BIN(f[hi]);
-      if(bin>LASTBIN)bin=LASTBIN;
-      if(bin<0)bin=0;
-      radix[bin]++;
-      if(bin<median)
-	countabove++;
-      else
-	countbelow++;
-    }
-    bi=b[i]-lowidth;
-    for(;lo<i && lo+lomin<i && b[lo]<=bi;lo++){
-      int bin=BIN(f[lo]);
-      if(bin>LASTBIN)bin=LASTBIN;
-      if(bin<0)bin=0;
-      radix[bin]--;
-      if(bin<median)
-	countabove--;
-      else
-	countbelow--;
+    int bi=b[i]>>16;
+    for(;hi<bi;hi++){
+      int bin=psy_dBquant(f+hi);
+      barkradix[bin]++;
+      if(bin<=median)
+	barkcountbelow++;
+    }
+    bi=b[i]&0xffff;
+    for(;lo<bi;lo++){
+      int bin=psy_dBquant(f+lo);
+      barkradix[bin]--;
+      if(bin<=median)
+	barkcountbelow--;
+    }
+
+    bi=i+(fixed>>1);
+    if(bi<n){
+      int bin=psy_dBquant(f+bi);
+      fixedradix[bin]++;
+      fixedc++;
+      if(bin<=median)
+	fixedcountbelow++;
+    }
+
+    bi-=fixed;
+    if(bi>=0){
+      int bin=psy_dBquant(f+bi);
+      fixedradix[bin]--;
+      fixedc--;
+      if(bin<=median)
+	fixedcountbelow--;
     }
 
     /* move the median if needed */
-    if(countabove+countbelow){
-      threshi = thresh[i]*(countabove+countbelow);
-
-      while(threshi>countbelow && median>0){
-	median--;
-	countabove-=radix[median];
-	countbelow+=radix[median];
+    {
+      int bark_th = (thresh[i]*(hi-lo)+512)/1024;
+      int fixed_th = (thresh[i]*(fixedc)+512)/1024;
+
+      while(bark_th>=barkcountbelow && 
+	    fixed_th>=fixedcountbelow /* && median<LASTBIN by rep invariant */
+	    ){
+	median++;
+	barkcountbelow+=barkradix[median];
+	fixedcountbelow+=fixedradix[median];
       }
 
-      while(threshi<(countbelow-radix[median]) &&
-	    median<LASTBIN){
-	countabove+=radix[median];
-	countbelow-=radix[median];
-	median++;
+      while(bark_th<barkcountbelow ||
+	    fixed_th<fixedcountbelow /* && median>=0 by rep invariant */
+	    ){
+	barkcountbelow-=barkradix[median];
+	fixedcountbelow-=fixedradix[median];
+	median--;
       }
     }
-    noise[i]=BINdB(median)+off[i];
+
+    noise[i]= (median+1)*.5f+off[i];
   }
 
 }
@@ -607,8 +648,7 @@
 float _vp_compute_mask(vorbis_look_psy *p,
                       float *fft, 
                       float *mdct, 
-		      float *flr, 
-		      float *decay,
+		      float *mask, 
                       float specmax){
   int i,n=p->n;
   float localmax=NEGINF;
@@ -618,37 +658,28 @@
   float *maxseed=alloca(sizeof(float)*p->total_octave_lines);
   for(i=0;i<p->total_octave_lines;i++)minseed[i]=maxseed[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_nn(fft[i]);
+  /* Find the highest peak so we know the limits */
+  for(i=0;i<n;i++)
     if(fft[i]>localmax)localmax=fft[i];
-  }
   if(specmax<localmax)specmax=localmax;
 
-
-  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,
+    bark_noise_median(n,p->bark,mdct,mask,
                       p->vi->noisewindowlo,
                       p->vi->noisewindowhi,
                       p->vi->noisewindowlomin,
                       p->vi->noisewindowhimin,
                       p->noisemedian,
-		      p->noiseoffset);
+		      p->noiseoffset,
+		      p->vi->noisewindowfixed);
     /* 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);
+      if(mask[i]>specmax+p->vi->noisemaxsupp)
+	mask[i]=specmax+p->vi->noisemaxsupp;
+    _analysis_output("noise",seq,mask,n,0,0);
   }else{
-    for(i=0;i<n;i++)flr[i]=NEGINF;
+    for(i=0;i<n;i++)mask[i]=NEGINF;
   }
 
   /* set the ATH (floating below localmax, not global max by a
@@ -659,52 +690,32 @@
 
     for(i=0;i<n;i++){
       float av=p->ath[i]+att;
-      if(av>flr[i])flr[i]=av;
+      if(av>mask[i])mask[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,minseed,maxseed,specmax);
-  bound_loop(p,mdct,maxseed,flr,p->vi->bound_att_dB);
-  _analysis_output("minseed",seq,minseed,p->total_octave_lines,0,0);
-  _analysis_output("maxseed",seq,maxseed,p->total_octave_lines,0,0);
-  max_seeds(p,minseed,maxseed,flr);
-  _analysis_output("final",seq,flr,n,0,0);
+  seed_loop(p,
+	    (const float ***)p->tonecurves,
+	    (const float **)p->peakatt,fft,mask,minseed,maxseed,specmax);
+  bound_loop(p,mdct,maxseed,mask,p->vi->bound_att_dB);
+  max_seeds(p,minseed,maxseed,mask);
 
   /* 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;
-
 
+  for(i=0;i<n;i++)if(mdct[i]>=mask[i])break;
+  if(i==n)
+    for(i=0;i<n;i++)mask[i]=NEGINF;
+  else
+    for(i=0;i<n;i++)fft[i]=max(mdct[i],fft[i]);
   seq++;
 
   return(specmax);
-}
-
-
-/* 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));
 }
 
 float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){

1.20      +5 -9      vorbis/lib/psy.h

Index: psy.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/psy.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- psy.h	2001/02/26 03:50:43	1.19
+++ psy.h	2001/05/27 06:44:00	1.20
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: random psychoacoustics (not including preecho)
- last mod: $Id: psy.h,v 1.19 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: psy.h,v 1.20 2001/05/27 06:44:00 xiphmont Exp $
 
  ********************************************************************/
 
@@ -52,14 +52,12 @@
   float noisewindowhi;
   int   noisewindowlomin;
   int   noisewindowhimin;
+  int   noisewindowfixed;
   float noisemedian[P_BANDS*2];
 
   float max_curve_dB;
   float bound_att_dB;
 
-  /* decay setup */
-  float attack_coeff;
-  float decay_coeff;
 } vorbis_info_psy;
 
 typedef struct {
@@ -68,12 +66,12 @@
 
   float ***tonecurves;
   float **peakatt;
-  float *noisemedian;
+  int   *noisemedian;
   float *noiseoffset;
 
   float *ath;
   long  *octave;             /* in n.ocshift format */
-  float *bark;
+  unsigned long *bark;
 
   long  firstoc;
   long  shiftoc;
@@ -92,10 +90,8 @@
 extern float  _vp_compute_mask(vorbis_look_psy *p,
                                float *fft, 
                                float *mdct, 
-			       float *floor,
-			       float *decay,
+			       float *mask,
                                float prev_maxamp);
-extern void _vp_apply_floor(vorbis_look_psy *p,float *f,float *flr);
 extern float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd);
 
 #endif

1.15      +69 -103   vorbis/lib/psytune.c

Index: psytune.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/psytune.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- psytune.c	2001/02/26 03:50:43	1.14
+++ psytune.c	2001/05/27 06:44:00	1.15
@@ -12,7 +12,7 @@
 
  function: simple utility that runs audio through the psychoacoustics
            without encoding
- last mod: $Id: psytune.c,v 1.14 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: psytune.c,v 1.15 2001/05/27 06:44:00 xiphmont Exp $
 
  ********************************************************************/
 
@@ -33,7 +33,7 @@
 
 static vorbis_info_psy _psy_set0={
   1,/*athp*/
-  0,/*decayp*/
+  1,/*decayp*/
 
   -100.f,
   -140.f,
@@ -43,38 +43,30 @@
   /*     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 */
   {
    {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*63*/
    {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*88*/
    {-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f,-999.f}, /*125*/
-   //   {-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-100.}, /*175*/
-   //   {-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-100.}, /*250*/
-   //   {-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-100.}, /*350*/
-   //   {-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-100.}, /*500*/
-   //   {-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-99.,-100.}, /*700*/
-
-   //   {-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.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*/
+
+   {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/
+   {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/
+   {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/
+   {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/
+   {-35.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*/
+   {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/
+   {-35.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,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*5600*/
+   {-35.f,-35.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*4000*/
+   {-35.f,-35.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,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/
-   {-30.f,-30.f,-30.f,-40.f,-40.f,-45.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*11500*/
-   {-30.f,-30.f,-30.f,-35.f,-35.f,-45.f,-50.f,-60.f,-70.f,-80.f,-90.f}, /*16000*/
+   {-30.f,-30.f,-33.f,-35.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*8000*/
+   {-30.f,-30.f,-33.f,-35.f,-35.f,-45.f,-50.f,-60.f,-70.f,-90.f,-100.f}, /*11500*/
+   {-24.f,-24.f,-26.f,-32.f,-32.f,-42.f,-50.f,-60.f,-70.f,-90.f,-100.f}, /*16000*/
+
   },
 
   1,/* peakattp */
@@ -98,38 +90,37 @@
   },
 
   1,/*noisemaskp */
-  -0.f,  /* suppress any noise curve over maxspec+n */
+  -24.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*/
-   .200f, /*700*/
-   .300f, /*1000*/
-   .400f, /*1400*/
-   .400f, /*2000*/
-   .400f, /*2800*/
-   .700f, /*4000*/
-   .900f, /*5600*/
-   .900f, /*8000*/
-   .900f, /*11500*/
-   .900f, /*16000*/
+  {.000f, 0.f, /*63*/
+   .000f, 0.f, /*88*/
+   .000f, 0.f, /*125*/
+   .000f, 0.f, /*175*/
+   .000f, 0.f, /*250*/
+   .000f, 0.f, /*350*/
+   .000f, 0.f, /*500*/
+   .200f, 0.f, /*700*/
+   .300f, 0.f, /*1000*/
+   .400f, 0.f, /*1400*/
+   .400f, 0.f, /*2000*/
+   .400f, 0.f, /*2800*/
+   .700f, 0.f, /*4000*/
+   .850f, 0.f, /*5600*/
+   .900f, 0.f, /*8000*/
+   .900f, 0.f, /*11500*/
+   .900f, 1.f, /*16000*/
   },
  
-  105.f,  /* even decade + 5 is important; saves an rint() later in a
+  95.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -28.,
 
-  -0.f, -.004f   /* attack/decay control */
 };
 
-static int noisy=0;
+static int noisy=1;
 void analysis(char *base,int i,float *v,int n,int bark,int dB){
   if(noisy){
     int j;
@@ -148,7 +139,7 @@
           fprintf(of,"%g ",(float)j);
       
         if(dB){
-	  fprintf(of,"%g\n",todB(fabs(v[j])));
+	  fprintf(of,"%g\n",todB(fabs(v+j)));
         }else{
           fprintf(of,"%g\n",v[j]);
         }
@@ -158,41 +149,9 @@
   }
 }
 
-typedef struct {
-  long n;
-  int ln;
-  int  m;
-  int *linearmap;
-
-  void *vi;
-  lpc_lookup lpclook;
-  float *lsp_look;
-
-} vorbis_look_floor0;
-
-extern float _curve_to_lpc(float *curve,float *lpc,
-			   vorbis_look_floor0 *l);
-
 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;
@@ -210,11 +169,10 @@
   signed char *buffer,*buffer2;
   mdct_lookup m_look;
   drft_lookup f_look;
+  drft_lookup f_look2;
   vorbis_look_psy p_look;
   long i,j,k;
 
-  vorbis_look_floor0 floorlook;
-
   int ath=0;
   int decayp=0;
 
@@ -260,8 +218,8 @@
   window=_vorbis_window(0,framesize,framesize/2,framesize/2);
   mdct_init(&m_look,framesize);
   drft_init(&f_look,framesize);
+  drft_init(&f_look2,framesize/2);
   _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++)
@@ -329,35 +287,43 @@
         }
 
         analysis("mask",frameno,flr,framesize/2,0,0);
-
-	for(j=0;j<framesize/2;j++)
-	  mask[j]=flr[j]+140.;
 
-	amp=sqrt(_curve_to_lpc(mask,mask,&floorlook));
-	vorbis_lpc_to_lsp(mask,mask,floorlook.m);
-	vorbis_lsp_to_curve(flr,floorlook.linearmap,floorlook.n,floorlook.ln,
-			    mask,floorlook.m,amp,140.);
+	mask[framesize-1]=0.;
+	mask[0]=0.;
+	for(j=1;j<framesize-1;j+=2){
+	  mask[j]=todB(pcm[i]+((j+1)>>1));
+	  mask[j+1]=0;
+	}
 
-	analysis("floor",frameno,flr,framesize/2,0,1);
+	analysis("lfft",frameno,mask,framesize,0,0);
+	drft_backward(&f_look,mask);
 
-	_vp_apply_floor(&p_look,pcm[i],flr);
+	analysis("cep",frameno,mask,framesize,0,0);
+	analysis("logcep",frameno,mask,framesize,0,1);
+	
 
 
-	analysis("quant",frameno,pcm[i],framesize/2,0,0);
+	/*for(j=0;j<framesize/2;j++){
+	  float val=fromdB(flr[j]);
+	  int p=rint(pcm[i][j]/val);
+	  pcm[i][j]=p*val;
+	  }*/
+
+	/*for(j=0;j<framesize/2;j++){
+	  float val=todB(pcm[i]+j);
+	  if(val+6.<flr[j])
+	    pcm[i][j]=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;
-	  }
+	  float val=rint(todB(pcm[i]+j)/6);
+	  if(pcm[i][j]>0)
+	    pcm[i][j]=fromdB(val*6);
+	  else
+	    pcm[i][j]=-fromdB(val*6);
         }
-	
+
+
         analysis("final",frameno,pcm[i],framesize/2,0,1);
 
         /* take it back to time */

1.7       +5 -1      vorbis/lib/registry.c

Index: registry.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/registry.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- registry.c	2001/02/26 03:50:43	1.6
+++ registry.c	2001/05/27 06:44:00	1.7
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: registry for time, floor, res backends and channel mappings
- last mod: $Id: registry.c,v 1.6 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: registry.c,v 1.7 2001/05/27 06:44:00 xiphmont Exp $
 
  ********************************************************************/
 
@@ -24,7 +24,9 @@
 
 extern vorbis_func_time      time0_exportbundle;
 extern vorbis_func_floor     floor0_exportbundle;
+extern vorbis_func_floor     floor1_exportbundle;
 extern vorbis_func_residue   residue0_exportbundle;
+extern vorbis_func_residue   residue1_exportbundle;
 extern vorbis_func_mapping   mapping0_exportbundle;
 
 vorbis_func_time      *_time_P[]={
@@ -33,10 +35,12 @@
 
 vorbis_func_floor     *_floor_P[]={
   &floor0_exportbundle,
+  &floor1_exportbundle,
 };
 
 vorbis_func_residue   *_residue_P[]={
   &residue0_exportbundle,
+  &residue1_exportbundle,
 };
 
 vorbis_func_mapping   *_mapping_P[]={

1.6       +3 -3      vorbis/lib/registry.h

Index: registry.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/registry.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- registry.h	2001/02/26 03:50:43	1.5
+++ registry.h	2001/05/27 06:44:00	1.6
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: registry for time, floor, res backends and channel mappings
- last mod: $Id: registry.h,v 1.5 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: registry.h,v 1.6 2001/05/27 06:44:00 xiphmont Exp $
 
  ********************************************************************/
 
@@ -23,8 +23,8 @@
 #define VI_TRANSFORMB 1
 #define VI_WINDOWB 1
 #define VI_TIMEB 1
-#define VI_FLOORB 1
-#define VI_RESB 1
+#define VI_FLOORB 2
+#define VI_RESB 2
 #define VI_MAPB 1
 
 extern vorbis_func_time      *_time_P[];

1.27      +146 -24   vorbis/lib/res0.c

Index: res0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/res0.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- res0.c	2001/02/26 03:50:43	1.26
+++ res0.c	2001/05/27 06:44:01	1.27
@@ -7,11 +7,11 @@
  *                                                                  *
  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
-
+ *                                                                  *
  ********************************************************************
 
- function: residue backend 0 implementation
- last mod: $Id: res0.c,v 1.26 2001/02/26 03:50:43 xiphmont Exp $
+ function: residue backend 0 and 1 implementation
+ last mod: $Id: res0.c,v 1.27 2001/05/27 06:44:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -170,8 +170,8 @@
 
 /* does not guard against invalid settings; eg, a subn of 16 and a
    subgroup request of 32.  Max subn of 128 */
-static int _testhack(float *vec,int n,vorbis_look_residue0 *look,
-		     int auxparts,int auxpartnum){
+static int _interleaved_testhack(float *vec,int n,vorbis_look_residue0 *look,
+				 int auxparts,int auxpartnum){
   vorbis_info_residue0 *info=look->info;
   int i,j=0;
   float max,localmax=0.f;
@@ -191,9 +191,9 @@
   while(1){
     entropy[j]=localmax;
     n>>=1;
+    if(!n)break;
     j++;
 
-    if(n<=0)break;
     for(i=0;i<n;i++){
       temp[i]+=temp[i+n];
     }
@@ -211,6 +211,71 @@
   return(i);
 }
 
+static int _testhack(float *vec,int n,vorbis_look_residue0 *look,
+		     int auxparts,int auxpartnum){
+  vorbis_info_residue0 *info=look->info;
+  int i,j=0;
+  float max,localmax=0.f;
+  float temp[128];
+  float entropy[8];
+
+  /* setup */
+  for(i=0;i<n;i++)temp[i]=fabs(vec[i]);
+
+  /* handle case subgrp==1 outside */
+  for(i=0;i<n;i++)
+    if(temp[i]>localmax)localmax=temp[i];
+  max=localmax;
+
+  for(i=0;i<n;i++)temp[i]=rint(temp[i]);
+  
+  while(n){
+    entropy[j]=localmax;
+    n>>=1;
+    j++;
+    if(!n)break;
+    for(i=0;i<n;i++){
+      temp[i]=temp[i*2]+temp[i*2+1];
+    }
+    localmax=0.f;
+    for(i=0;i<n;i++)
+      if(temp[i]>localmax)localmax=temp[i];
+  }
+
+  for(i=0;i<auxparts-1;i++)
+    if(auxpartnum<info->blimit[i] &&
+       entropy[info->subgrp[i]]<=info->entmax[i] &&
+       max<=info->ampmax[i])
+      break;
+
+  return(i);
+}
+
+static int _interleaved_encodepart(oggpack_buffer *opb,float *vec, int n,
+				   int stages, codebook **books,int mode,
+				   int part){
+  int i,j=0,bits=0;
+  if(stages){
+    int dim=books[j]->dim;
+    int step=n/dim;
+    for(i=0;i<step;i++){
+      int entry=vorbis_book_besterror(books[j],vec+i,step,0);
+#ifdef TRAIN_RESENT      
+      {
+	char buf[80];
+	FILE *f;
+	sprintf(buf,"res0_%da%d_%d.vqd",mode,j,part);
+	f=fopen(buf,"a");
+	fprintf(f,"%d\n",entry);
+	fclose(f);
+      }
+#endif
+      bits+=vorbis_book_encode(books[j],entry,opb);
+    }
+  }
+  return(bits);
+}
+ 
 static int _encodepart(oggpack_buffer *opb,float *vec, int n,
                        int stages, codebook **books,int mode,int part){
   int i,j=0,bits=0;
@@ -218,7 +283,7 @@
     int dim=books[j]->dim;
     int step=n/dim;
     for(i=0;i<step;i++){
-      int entry=vorbis_book_besterror(books[j],vec+i,step,0);
+      int entry=vorbis_book_besterror(books[j],vec+i*dim,1,0);
 #ifdef TRAIN_RESENT      
       {
         char buf[80];
@@ -235,14 +300,15 @@
   return(bits);
 }
 
-static int _decodepart(oggpack_buffer *opb,float *work,float *vec, int n,
-		       int stages, codebook **books){
+/* doesn;t yet deal with cascading */
+static int _interleaved_decodepart(oggpack_buffer *opb,float *work,
+				   float *vec, int n,
+				   int stages, codebook **books){
   int i;
   
   memset(work,0,sizeof(float)*n);
   if(stages){
-    int dim=books[0]->dim;
-    int step=n/dim;
+    int step=n/books[0]->dim;
     if(s_vorbis_book_decodevs(books[0],work,opb,step,0)==-1)
       return(-1);
   }
@@ -253,8 +319,29 @@
   return(0);
 }
 
-int res0_forward(vorbis_block *vb,vorbis_look_residue *vl,
-	    float **in,int ch){
+static int _decodepart(oggpack_buffer *opb,float *work,
+		       float *vec, int n,
+		       int stages, codebook **books){
+  int i;
+  
+  memset(work,0,sizeof(float)*n);
+  if(stages){
+    if(s_vorbis_book_decodev(books[0],work,opb,n,0)==-1)
+      return(-1);
+  }
+  
+  for(i=0;i<n;i++)
+    vec[i]*=work[i];
+  
+  return(0);
+}
+
+static int _01forward(vorbis_block *vb,vorbis_look_residue *vl,
+		      float **in,int ch,
+		      int (*classify)(float *,int,vorbis_look_residue0 *,
+				      int,int),
+		      int (*encode)(oggpack_buffer *,float *,int,int,
+				    codebook **,int,int)){
   long i,j,k,l;
   vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   vorbis_info_residue0 *info=look->info;
@@ -288,12 +375,13 @@
 
   for(i=info->begin,l=0;i<info->end;i+=samples_per_partition,l++){
     for(j=0;j<ch;j++)
-      /* do the partition decision based on the number of 'bits'
-         needed to encode the block */
+      /* do the partition decision based on the 'entropy'
+         int the block */
       partword[j][l]=
-	_testhack(in[j]+i,samples_per_partition,look,possible_partitions,l);
+	classify(in[j]+i,samples_per_partition,look,possible_partitions,l);
   
   }
+
   /* we code the partition words for each channel, then the residual
      words for a partition per channel until we've written all the
      residual words for that partition word.  Then write the next
@@ -312,9 +400,9 @@
     for(k=0;k<partitions_per_word;k++,l++,i+=samples_per_partition)
       for(j=0;j<ch;j++){
         /*resbits[partword[j][l]]+=*/
-	resbitsT+=_encodepart(&vb->opb,in[j]+i,samples_per_partition,
-			      info->secondstages[partword[j][l]],
-			      look->partbooks[partword[j][l]],look->map,partword[j][l]);
+	resbitsT+=encode(&vb->opb,in[j]+i,samples_per_partition,
+			 info->secondstages[partword[j][l]],
+			 look->partbooks[partword[j][l]],look->map,partword[j][l]);
         resvals[partword[j][l]]+=samples_per_partition;
       }
       
@@ -332,7 +420,10 @@
 }
 
 /* a truncated packet here just means 'stop working'; it's not an error */
-int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){
+static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
+		      float **in,int ch,
+		      int (*decodepart)(oggpack_buffer *,float *,float *,
+					int,int,codebook **)){
   long i,j,k,l,transend=vb->pcmend/2;
   vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   vorbis_info_residue0 *info=look->info;
@@ -361,13 +452,13 @@
       if(partword[j]==NULL)goto errout;
     }
     
-    /* now we decode interleaved residual values for the partitions */
+    /* now we decode residual values for the partitions */
     for(k=0;k<partitions_per_word;k++,l++,i+=samples_per_partition)
       for(j=0;j<ch;j++){
         int part=partword[j][k];
-	if(_decodepart(&vb->opb,work,in[j]+i,samples_per_partition,
-		    info->secondstages[part],
-		       look->partbooks[part])==-1)goto eopbreak;
+	if(decodepart(&vb->opb,work,in[j]+i,samples_per_partition,
+		      info->secondstages[part],
+		      look->partbooks[part])==-1)goto eopbreak;
       }
   }
 
@@ -385,6 +476,26 @@
   return(0);
 }
 
+/* residue 0 and 1 are just slight variants of one another. 0 is
+   interleaved, 1 is not */
+int res0_forward(vorbis_block *vb,vorbis_look_residue *vl,
+	    float **in,int ch){
+  return(_01forward(vb,vl,in,ch,_interleaved_testhack,_interleaved_encodepart));
+}
+
+int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){
+    return(_01inverse(vb,vl,in,ch,_interleaved_decodepart));
+}
+
+int res1_forward(vorbis_block *vb,vorbis_look_residue *vl,
+	    float **in,int ch){
+  return(_01forward(vb,vl,in,ch,_testhack,_encodepart));
+}
+
+int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){
+    return(_01inverse(vb,vl,in,ch,_decodepart));
+}
+
 vorbis_func_residue residue0_exportbundle={
   &res0_pack,
   &res0_unpack,
@@ -394,4 +505,15 @@
   &res0_free_look,
   &res0_forward,
   &res0_inverse
+};
+
+vorbis_func_residue residue1_exportbundle={
+  &res0_pack,
+  &res0_unpack,
+  &res0_look,
+  &res0_copy_info,
+  &res0_free_info,
+  &res0_free_look,
+  &res1_forward,
+  &res1_inverse
 };

1.16      +86 -5     vorbis/lib/scales.h

Index: scales.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/scales.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- scales.h	2001/02/26 03:50:43	1.15
+++ scales.h	2001/05/27 06:44:01	1.16
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: linear scale -> dB, Bark and Mel scales
- last mod: $Id: scales.h,v 1.15 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: scales.h,v 1.16 2001/05/27 06:44:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -22,10 +22,91 @@
 #include "os.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))
+#ifdef VORBIS_IEEE_FLOAT32
+static float todB_LOOKUP[256]={
+        -140.277330f, -139.633636f, -139.034372f, -138.473797f, 
+        -137.450747f, -136.535597f, -135.707743f, -134.951972f, 
+        -134.256730f, -133.613036f, -133.013772f, -132.453198f, 
+        -131.430147f, -130.514997f, -129.687144f, -128.931372f, 
+        -128.236130f, -127.592437f, -126.993172f, -126.432598f, 
+        -125.409547f, -124.494397f, -123.666544f, -122.910772f, 
+        -122.215530f, -121.571837f, -120.972572f, -120.411998f, 
+        -119.388947f, -118.473797f, -117.645944f, -116.890173f, 
+        -116.194930f, -115.551237f, -114.951972f, -114.391398f, 
+        -113.368347f, -112.453198f, -111.625344f, -110.869573f, 
+        -110.174331f, -109.530637f, -108.931372f, -108.370798f, 
+        -107.347748f, -106.432598f, -105.604744f, -104.848973f, 
+        -104.153731f, -103.510037f, -102.910773f, -102.350198f, 
+        -101.327148f, -100.411998f,  -99.584144f,  -98.828373f, 
+         -98.133131f,  -97.489437f,  -96.890173f,  -96.329598f, 
+         -95.306548f,  -94.391398f,  -93.563544f,  -92.807773f, 
+         -92.112531f,  -91.468837f,  -90.869573f,  -90.308998f, 
+         -89.285948f,  -88.370798f,  -87.542944f,  -86.787173f, 
+         -86.091931f,  -85.448237f,  -84.848973f,  -84.288398f, 
+         -83.265348f,  -82.350198f,  -81.522344f,  -80.766573f, 
+         -80.071331f,  -79.427637f,  -78.828373f,  -78.267799f, 
+         -77.244748f,  -76.329598f,  -75.501745f,  -74.745973f, 
+         -74.050731f,  -73.407038f,  -72.807773f,  -72.247199f, 
+         -71.224148f,  -70.308998f,  -69.481145f,  -68.725373f, 
+         -68.030131f,  -67.386438f,  -66.787173f,  -66.226599f, 
+         -65.203548f,  -64.288399f,  -63.460545f,  -62.704774f, 
+         -62.009531f,  -61.365838f,  -60.766573f,  -60.205999f, 
+         -59.182948f,  -58.267799f,  -57.439945f,  -56.684174f, 
+         -55.988932f,  -55.345238f,  -54.745973f,  -54.185399f, 
+         -53.162349f,  -52.247199f,  -51.419345f,  -50.663574f, 
+         -49.968332f,  -49.324638f,  -48.725374f,  -48.164799f, 
+         -47.141749f,  -46.226599f,  -45.398745f,  -44.642974f, 
+         -43.947732f,  -43.304038f,  -42.704774f,  -42.144199f, 
+         -41.121149f,  -40.205999f,  -39.378145f,  -38.622374f, 
+         -37.927132f,  -37.283438f,  -36.684174f,  -36.123599f, 
+         -35.100549f,  -34.185399f,  -33.357545f,  -32.601774f, 
+         -31.906532f,  -31.262838f,  -30.663574f,  -30.102999f, 
+         -29.079949f,  -28.164799f,  -27.336945f,  -26.581174f, 
+         -25.885932f,  -25.242238f,  -24.642974f,  -24.082400f, 
+         -23.059349f,  -22.144199f,  -21.316346f,  -20.560574f, 
+         -19.865332f,  -19.221639f,  -18.622374f,  -18.061800f, 
+         -17.038749f,  -16.123599f,  -15.295746f,  -14.539974f, 
+         -13.844732f,  -13.201039f,  -12.601774f,  -12.041200f, 
+         -11.018149f,  -10.103000f,   -9.275146f,   -8.519375f, 
+          -7.824132f,   -7.180439f,   -6.581174f,   -6.020600f, 
+          -4.997549f,   -4.082400f,   -3.254546f,   -2.498775f, 
+          -1.803533f,   -1.159839f,   -0.560574f,    0.000000f, 
+           1.023050f,    1.938200f,    2.766054f,    3.521825f, 
+	   4.217067f,    4.860761f,    5.460025f,    6.020600f, 
+           7.043650f,    7.958800f,    8.786654f,    9.542425f, 
+          10.237667f,   10.881361f,   11.480625f,   12.041200f, 
+          13.064250f,   13.979400f,   14.807254f,   15.563025f, 
+          16.258267f,   16.901961f,   17.501225f,   18.061800f, 
+          19.084850f,   20.000000f,   20.827854f,   21.583625f, 
+          22.278867f,   22.922561f,   23.521825f,   24.082400f, 
+          25.105450f,   26.020600f,   26.848453f,   27.604225f, 
+          28.299467f,   28.943161f,   29.542425f,   30.102999f, 
+          31.126050f,   32.041200f,   32.869053f,   33.624825f, 
+          34.320067f,   34.963760f,   35.563025f,   36.123599f, 
+          37.146650f,   38.061800f,   38.889653f,   39.645424f, 
+          40.340667f,   40.984360f,   41.583625f,   42.144199f, 
+          43.167250f,   44.082399f,   44.910253f,   45.666024f, 
+          46.361266f,   47.004960f,   47.604225f,   48.164799f, 
+          49.187850f,   50.102999f,   50.930853f,   51.686624f
+};
+
+static float todB(const float *x){
+  ogg_int32_t *i=(ogg_int32_t *)x;
+  ogg_int32_t temp=((*i&0x7fffffff)-0x33cfffff)>>20;
+  if(temp<0)return -400.f;
+  return(todB_LOOKUP[temp]);
+}
+
+#define todB_nn(x) todB(x)
+
+#else
+
+#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)
+
+#endif 
+
+#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

1.22      +29 -1     vorbis/lib/synthesis.c

Index: synthesis.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/synthesis.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- synthesis.c	2001/02/26 03:50:43	1.21
+++ synthesis.c	2001/05/27 06:44:01	1.22
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.21 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: synthesis.c,v 1.22 2001/05/27 06:44:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -70,6 +70,34 @@
   type=ci->map_type[ci->mode_param[mode]->mapping];
 
   return(_mapping_P[type]->inverse(vb,b->mode[mode]));
+}
+
+long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
+  codec_setup_info     *ci=vi->codec_setup;
+  oggpack_buffer       opb;
+  int                  type,mode,i;
+ 
+  oggpack_readinit(&opb,op->packet,op->bytes);
+
+  /* Check the packet type */
+  if(oggpack_read(&opb,1)!=0){
+    /* Oops.  This is not an audio data packet */
+    return(OV_ENOTAUDIO);
+  }
+
+  {
+    int modebits=0;
+    int v=ci->modes;
+    while(v>1){
+      modebits++;
+      v>>=1;
+    }
+
+    /* read our mode and pre/post windowsize */
+    mode=oggpack_read(&opb,modebits);
+  }
+  if(mode==-1)return(OV_EBADPACKET);
+  return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
 }
 
 

1.7       +3 -2      vorbis/lib/vorbisenc.c

Index: vorbisenc.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/vorbisenc.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- vorbisenc.c	2001/02/26 03:50:43	1.6
+++ vorbisenc.c	2001/05/27 06:44:01	1.7
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: simple programmatic interface for encoder mode setup
- last mod: $Id: vorbisenc.c,v 1.6 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: vorbisenc.c,v 1.7 2001/05/27 06:44:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -139,7 +139,8 @@
 
   /* adjust for sample rate */
   for(i=0;i<ci->floors;i++)
-    ((vorbis_info_floor0 *)(ci->floor_param[i]))->rate=rate;
+    if(ci->floor_type[i]==0)
+      ((vorbis_info_floor0 *)(ci->floor_param[i]))->rate=rate;
 
   /* adjust for channels; all our mappings use submap zero now */
   /* yeah, OK, _ogg_calloc did this for us.  But it's a reminder/placeholder */

1.45      +463 -215  vorbis/lib/vorbisfile.c

Index: vorbisfile.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/vorbisfile.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- vorbisfile.c	2001/03/27 07:04:51	1.44
+++ vorbisfile.c	2001/05/27 06:44:01	1.45
@@ -7,11 +7,11 @@
  *                                                                  *
  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
-
+ *                                                                  *
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.44 2001/03/27 07:04:51 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.45 2001/05/27 06:44:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -57,7 +57,8 @@
  * grokking near the end of the file */
 
 /* read a little more data from the file/pipe into the ogg_sync framer */
-#define CHUNKSIZE 4096
+#define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well
+                          over 8k gets what they deserve */
 static long _get_data(OggVorbis_File *vf){
   errno=0;
   if(vf->datasource){
@@ -233,6 +234,7 @@
 
   if(serialno)*serialno=ogg_page_serialno(og_ptr);
   ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
+  vf->ready_state=STREAMSET;
   
   /* extract the initial header from the first page and verify that the
      Ogg bitstream is in fact Vorbis data */
@@ -279,24 +281,19 @@
    able to open and use damaged bitstreams as well as we can.  Just
    watch out for missing information for links in the OggVorbis_File
    struct */
-static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first_i,
-				  vorbis_comment *first_c,
-				  long dataoffset){
+static void _prefetch_all_headers(OggVorbis_File *vf, long dataoffset){
   ogg_page og;
   int i,ret;
   
-  vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
-  vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
+  vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(vorbis_info));
+  vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(vorbis_info));
   vf->dataoffsets=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
   vf->pcmlengths=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
   vf->serialnos=_ogg_malloc(vf->links*sizeof(long));
   
   for(i=0;i<vf->links;i++){
-    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_i,sizeof(vorbis_info));
-      memcpy(vf->vc+i,first_c,sizeof(vorbis_comment));
+    if(i==0){
+      /* we already grabbed the initial header earlier.  Just set the offset */
       vf->dataoffsets[i]=dataoffset;
     }else{
 
@@ -320,7 +317,7 @@
       while(1){
         ret=_get_prev_page(vf,&og);
         if(ret<0){
-	  /* this should not be possible, actually */
+	  /* this should not be possible */
           vorbis_info_clear(vf->vi+i);
           vorbis_comment_clear(vf->vc+i);
           break;
@@ -330,39 +327,32 @@
           vf->pcmlengths[i]=ogg_page_granulepos(&og);
           break;
         }
+	vf->offset=ret;
       }
     }
   }
 }
 
 static void _make_decode_ready(OggVorbis_File *vf){
-  if(vf->decode_ready)return;
+  if(vf->ready_state!=STREAMSET)return;
   if(vf->seekable){
     vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
   }else{
     vorbis_synthesis_init(&vf->vd,vf->vi);
   }    
   vorbis_block_init(&vf->vd,&vf->vb);
-  vf->decode_ready=1;
+  vf->ready_state=INITSET;
   return;
 }
 
-static int _open_seekable(OggVorbis_File *vf){
-  vorbis_info initial_i;
-  vorbis_comment initial_c;
-  long serialno,end;
-  int ret;
-  long dataoffset;
+static int _open_seekable2(OggVorbis_File *vf){
+  long serialno=vf->current_serialno,end;
+  long dataoffset=vf->offset;
   ogg_page og;
-  
-  /* is this even vorbis...? */
-  ret=_fetch_headers(vf,&initial_i,&initial_c,&serialno,NULL);
-  dataoffset=vf->offset;
-  ogg_stream_clear(&vf->os);
-  if(ret<0)return(ret);
-  
+
+  /* we're partially open and have a first link header state in
+     storage in vf */
   /* we can seek, so set out learning all about this file */
-  vf->seekable=1;
   (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
   vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
   
@@ -370,7 +360,7 @@
      Most OggVorbis files will contain a single logical bitstream */
   end=_get_prev_page(vf,&og);
   if(end<0){
-    ogg_stream_clear(&vf->os);
+    ov_clear(vf);
     return(end);
   }
 
@@ -380,7 +370,7 @@
     /* Chained bitstream. Bisect-search each logical bitstream
        section.  Do so based on serial number only */
     if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
-      ogg_stream_clear(&vf->os);
+      ov_clear(vf);
       return(OV_EREAD);
     }
 
@@ -388,30 +378,15 @@
 
     /* Only one logical bitstream */
     if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
-      ogg_stream_clear(&vf->os);
+      ov_clear(vf);
       return(OV_EREAD);
     }
 
   }
 
-  _prefetch_all_headers(vf,&initial_i,&initial_c,dataoffset);
+  /* the initial header memory is referenced by vf after; don't free it */
+  _prefetch_all_headers(vf,dataoffset);
   return(ov_raw_seek(vf,0));
-
-}
-
-static int _open_nonseekable(OggVorbis_File *vf){
-  int ret;
-  /* we cannot seek. Set up a 'single' (current) logical bitstream entry  */
-  vf->links=1;
-  vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
-  vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
-
-  /* Try to fetch the headers, maintaining all the storage */
-  if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0)
-    return(ret);
-  _make_decode_ready(vf);
-
-  return 0;
 }
 
 /* clear out the current logical bitstream decoder */ 
@@ -419,7 +394,7 @@
   ogg_stream_clear(&vf->os);
   vorbis_dsp_clear(&vf->vd);
   vorbis_block_clear(&vf->vb);
-  vf->decode_ready=0;
+  vf->ready_state=OPENED;
 
   vf->bittrack=0.f;
   vf->samptrack=0.f;
@@ -445,11 +420,11 @@
     
     /* process a packet if we can.  If the machine isn't loaded,
        neither is a page */
-    if(vf->decode_ready){
+    if(vf->ready_state==INITSET){
       ogg_packet op;
       int result=ogg_stream_packetout(&vf->os,&op);
       ogg_int64_t granulepos;
-      
+
       if(result==-1)return(OV_HOLE); /* hole in the data. */
       if(result>0){
         /* got a packet.  process it */
@@ -499,18 +474,26 @@
         }
       }
     }
-
-    if(!readp)return(0);
-    if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof. leave unitialized */
 
-    /* bitrate tracking; add the header's bytes here, the body bytes
-       are done by packet above */
-    vf->bittrack+=og.header_len*8;
-
-    /* has our decoding just traversed a bitstream boundary? */
-    if(vf->decode_ready){
-      if(vf->current_serialno!=ogg_page_serialno(&og)){
-	_decode_clear(vf);
+    if(vf->ready_state>=STREAMSET){
+      if(!readp)return(0);
+      if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof. 
+							leave unitialized */
+      
+      /* bitrate tracking; add the header's bytes here, the body bytes
+	 are done by packet above */
+      vf->bittrack+=og.header_len*8;
+      
+      /* has our decoding just traversed a bitstream boundary? */
+      if(vf->ready_state==INITSET){
+	if(vf->current_serialno!=ogg_page_serialno(&og)){
+	  _decode_clear(vf);
+	  
+	  if(!vf->seekable){
+	    vorbis_info_clear(vf->vi);
+	    vorbis_comment_clear(vf->vc);
+	  }
+	}
       }
     }
 
@@ -526,33 +509,37 @@
        we're now nominally at the header of the next bitstream
     */
 
-    if(!vf->decode_ready){
+    if(vf->ready_state!=INITSET){ 
       int link;
-      if(vf->seekable){
-	vf->current_serialno=ogg_page_serialno(&og);
-	
-	/* match the serialno to bitstream section.  We use this rather than
-	   offset positions to avoid problems near logical bitstream
-	   boundaries */
-	for(link=0;link<vf->links;link++)
-	  if(vf->serialnos[link]==vf->current_serialno)break;
-	if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
-						   stream.  error out,
-						   leave machine
-						   uninitialized */
-	
-	vf->current_link=link;
-	
-	ogg_stream_init(&vf->os,vf->current_serialno);
-	ogg_stream_reset(&vf->os); 
-	
-      }else{
-	/* we're streaming */
-	/* fetch the three header packets, build the info struct */
-	
-	_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
-	vf->current_link++;
-	link=0;
+
+      if(vf->ready_state<STREAMSET){
+	if(vf->seekable){
+	  vf->current_serialno=ogg_page_serialno(&og);
+	  
+	  /* match the serialno to bitstream section.  We use this rather than
+	     offset positions to avoid problems near logical bitstream
+	     boundaries */
+	  for(link=0;link<vf->links;link++)
+	    if(vf->serialnos[link]==vf->current_serialno)break;
+	  if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
+						     stream.  error out,
+						     leave machine
+						     uninitialized */
+	  
+	  vf->current_link=link;
+	  
+	  ogg_stream_init(&vf->os,vf->current_serialno);
+	  ogg_stream_reset(&vf->os); 
+	  vf->ready_state=STREAMSET;
+	  
+	}else{
+	  /* we're streaming */
+	  /* fetch the three header packets, build the info struct */
+	  
+	  _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
+	  vf->current_link++;
+	  link=0;
+	}
       }
       
       _make_decode_ready(vf);
@@ -561,9 +548,65 @@
   }
 }
 
-/**********************************************************************
- * The helpers are over; it's all toplevel interface from here on out */
- 
+static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
+  if(f==NULL)return(-1);
+  return fseek(f,(int)off,whence);
+}
+
+static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
+		     long ibytes, ov_callbacks callbacks){
+  long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
+  int ret;
+
+  memset(vf,0,sizeof(OggVorbis_File));
+  vf->datasource=f;
+  vf->callbacks = callbacks;
+
+  /* init the framing state */
+  ogg_sync_init(&vf->oy);
+
+  /* perhaps some data was previously read into a buffer for testing
+     against other stream types.  Allow initialization from this
+     previously read data (as we may be reading from a non-seekable
+     stream) */
+  if(initial){
+    char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
+    memcpy(buffer,initial,ibytes);
+    ogg_sync_wrote(&vf->oy,ibytes);
+  }
+
+  /* can we seek? Stevens suggests the seek test was portable */
+  if(offset!=-1)vf->seekable=1;
+
+  /* No seeking yet; Set up a 'single' (current) logical bitstream
+     entry for partial open */
+  vf->links=1;
+  vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
+  vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
+  
+  /* Try to fetch the headers, maintaining all the storage */
+  if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
+    vf->datasource=NULL;
+    ov_clear(vf);
+  }else
+    vf->ready_state=PARTOPEN;
+  return(ret);
+}
+
+static int _ov_open2(OggVorbis_File *vf){
+  vf->ready_state=OPENED;
+  if(vf->seekable){
+    int ret=_open_seekable2(vf);
+    if(ret){
+      vf->datasource=NULL;
+      ov_clear(vf);
+    }
+    return(ret);
+  }
+  return 0;
+}
+
+
 /* clear out the OggVorbis_File struct */
 int ov_clear(OggVorbis_File *vf){
   if(vf){
@@ -594,11 +637,6 @@
   return(0);
 }
 
-static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
-  if(f==NULL)return(-1);
-  return fseek(f,(int)off,whence);
-}
-
 /* inspects the OggVorbis file and finds/documents all the logical
    bitstreams contained in it.  Tries to be tolerant of logical
    bitstream sections that are truncated/woogie. 
@@ -607,6 +645,13 @@
             0) OK
 */
 
+int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
+    ov_callbacks callbacks){
+  int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
+  if(ret)return ret;
+  return _ov_open2(vf);
+}
+
 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
   ov_callbacks callbacks = {
     (size_t (*)(void *, size_t, size_t, void *))  fread,
@@ -618,42 +663,32 @@
   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
 }
   
+/* Only partially open the vorbis file; test for Vorbisness, and load
+   the headers for the first chain.  Do not seek (although test for
+   seekability).  Use ov_test_open to finish opening the file, else
+   ov_clear to close/free it. Same return codes as open. */
 
-int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
+int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
     ov_callbacks callbacks)
 {
-  long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
-  int ret;
-
-  memset(vf,0,sizeof(OggVorbis_File));
-  vf->datasource=f;
-  vf->callbacks = callbacks;
-
-  /* init the framing state */
-  ogg_sync_init(&vf->oy);
+  return _ov_open1(f,vf,initial,ibytes,callbacks);
+}
 
-  /* perhaps some data was previously read into a buffer for testing
-     against other stream types.  Allow initialization from this
-     previously read data (as we may be reading from a non-seekable
-     stream) */
-  if(initial){
-    char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
-    memcpy(buffer,initial,ibytes);
-    ogg_sync_wrote(&vf->oy,ibytes);
-  }
+int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
+  ov_callbacks callbacks = {
+    (size_t (*)(void *, size_t, size_t, void *))  fread,
+    (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
+    (int (*)(void *))                             fclose,
+    (long (*)(void *))                            ftell
+  };
 
-  /* can we seek? Stevens suggests the seek test was portable */
-  if(offset!=-1){
-    ret=_open_seekable(vf);
-  }else{
-    ret=_open_nonseekable(vf);
-  }
-  if(ret){
-    vf->datasource=NULL;
-    ov_clear(vf);
-  }
-  return(ret);
+  return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
 }
+  
+int ov_test_open(OggVorbis_File *vf){
+  if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
+  return _ov_open2(vf);
+}
 
 /* How many logical bitstreams in this physical bitstream? */
 long ov_streams(OggVorbis_File *vf){
@@ -675,6 +710,7 @@
    vorbis_info structs */
 
 long ov_bitrate(OggVorbis_File *vf,int i){
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   if(i>=vf->links)return(OV_EINVAL);
   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
   if(i<0){
@@ -706,10 +742,13 @@
 }
 
 /* returns the actual bitrate since last call.  returns -1 if no
-   additional data to offer since last call (or at beginning of stream) */
+   additional data to offer since last call (or at beginning of stream),
+   EINVAL if stream is only partially open 
+*/
 long ov_bitrate_instant(OggVorbis_File *vf){
   int link=(vf->seekable?vf->current_link:0);
   long ret;
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   if(vf->samptrack==0)return(OV_FALSE);
   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
   vf->bittrack=0.f;
@@ -730,9 +769,11 @@
 
 /* returns: total raw (compressed) length of content if i==-1
             raw (compressed) length of that logical bitstream for i==0 to n
-	    -1 if the stream is not seekable (we can't know the length)
+	    OV_EINVAL if the stream is not seekable (we can't know the length)
+	    or if stream is only partially open
 */
 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
   if(i<0){
     long acc=0;
@@ -745,11 +786,13 @@
   }
 }
 
-/* returns: total PCM length (samples) of content if i==-1
-            PCM length (samples) of that logical bitstream for i==0 to n
-	    -1 if the stream is not seekable (we can't know the length)
+/* returns: total PCM length (samples) of content if i==-1 PCM length
+	    (samples) of that logical bitstream for i==0 to n
+	    OV_EINVAL if the stream is not seekable (we can't know the
+	    length) or only partially open 
 */
 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
   if(i<0){
     ogg_int64_t acc=0;
@@ -764,9 +807,11 @@
 
 /* returns: total seconds of content if i==-1
             seconds in that logical bitstream for i==0 to n
-	    -1 if the stream is not seekable (we can't know the length)
+	    OV_EINVAL if the stream is not seekable (we can't know the
+	    length) or only partially open 
 */
 double ov_time_total(OggVorbis_File *vf,int i){
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
   if(i<0){
     double acc=0;
@@ -780,69 +825,132 @@
 }
 
 /* seek to an offset relative to the *compressed* data. This also
-   immediately sucks in and decodes pages to update the PCM cursor. It
-   will cross a logical bitstream boundary, but only if it can't get
-   any packets out of the tail of the bitstream we seek to (so no
-   surprises). 
+   scans packets to update the PCM cursor. It will cross a logical
+   bitstream boundary, but only if it can't get any packets out of the
+   tail of the bitstream we seek to (so no surprises).
 
    returns zero on success, nonzero on failure */
 
 int ov_raw_seek(OggVorbis_File *vf,long pos){
-  int flag=0;
-  if(!vf->seekable)return(OV_ENOSEEK); /* don't dump machine if we can't seek */
+  ogg_stream_state work_os;
+
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
+  if(!vf->seekable)
+    return(OV_ENOSEEK); /* don't dump machine if we can't seek */
+
   if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
 
   /* clear out decoding machine state */
   vf->pcm_offset=-1;
   _decode_clear(vf);
   
-  /* seek */
   _seek_helper(vf,pos);
 
-  /* we need to make sure the pcm_offset is set.  We use the
-     _fetch_packet helper to process one packet with readp set, then
-     call it until it returns '0' with readp not set (the last packet
-     from a page has the 'granulepos' field set, and that's how the
-     helper updates the offset */
-
-  while(!flag){
-    switch(_process_packet(vf,1)){
-    case 0:case OV_EOF:
-      /* oh, eof. There are no packets remaining.  Set the pcm offset to
-	 the end of file */
-      vf->pcm_offset=ov_pcm_total(vf,-1);
-      return(0);
-    case OV_HOLE:
-      break;
-    case OV_EBADLINK:
-      goto seek_error;
-    default:
-      /* all OK */
-      flag=1;
-      break;
-    }
-  }
-  
-  while(1){
-    /* don't have to check each time through for the updated granule;
-       it's always the last complete packet on a page */
-    switch(_process_packet(vf,0)){
-    case 0:case OV_EOF:
-      /* the offset is set unless it's a bogus bitstream with no
-         offset information but that's not our fault.  We still run
-         gracefully, we're just missing the offset */
-      return(0);
-    case OV_EBADLINK:
-      goto seek_error;
-    default:
-      /* continue processing packets */
-      break;
+  /* we need to make sure the pcm_offset is set, but we don't want to
+     advance the raw cursor past good packets just to get to the first
+     with a granulepos.  That's not equivalent behavior to beginning
+     decoding as immediately after the seek position as possible.
+
+     So, a hack.  We use two stream states; a local scratch state and
+     a the shared vf->os stream state.  We use the local state to
+     scan, and the shared state as a buffer for later decode. 
+
+     Unfortuantely, on the last page we still advance to last packet
+     because the granulepos on the last page is not necessarily on a
+     packet boundary, and we need to make sure the granpos is
+     correct. 
+  */
+
+  {
+    ogg_page og;
+    ogg_packet op;
+    int lastblock=0;
+    int accblock=0;
+    int thisblock;
+    int eosflag;
+
+    memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
+					  it later even if we don't
+					  init it */
+
+    while(1){
+      if(vf->ready_state==STREAMSET){
+	/* snarf/scan a packet if we can */
+	int result=ogg_stream_packetout(&work_os,&op);
+      
+	if(result>0){
+
+	  if(vf->vi[vf->current_link].codec_setup)
+	    thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
+	  if(eosflag)
+	    ogg_stream_packetout(&vf->os,NULL);
+	  else
+	    if(lastblock)accblock+=(lastblock+thisblock)>>2;
+
+	  if(op.granulepos!=-1){
+	    int i,link=vf->current_link;
+	    ogg_int64_t granulepos=op.granulepos;
+	    
+	    for(i=0;i<link;i++)
+	      granulepos+=vf->pcmlengths[i];
+	    vf->pcm_offset=granulepos-accblock;
+	    break;
+	  }
+	  lastblock=thisblock;
+	  continue;
+	}
+      }
+      
+      if(!lastblock){
+	if(_get_next_page(vf,&og,-1)<0){
+	  vf->pcm_offset=ov_pcm_total(vf,-1);
+	  break;
+	}
+      }else{
+	/* huh?  Bogus stream with packets but no granulepos */
+	vf->pcm_offset=-1;
+	break;
+      }
+      
+      /* has our decoding just traversed a bitstream boundary? */
+      if(vf->ready_state==STREAMSET)
+	if(vf->current_serialno!=ogg_page_serialno(&og)){
+	_decode_clear(vf); /* clear out stream state */
+	ogg_stream_clear(&work_os);
+      }
+
+      if(vf->ready_state<STREAMSET){
+	int link;
+	
+	vf->current_serialno=ogg_page_serialno(&og);
+	for(link=0;link<vf->links;link++)
+	  if(vf->serialnos[link]==vf->current_serialno)break;
+	if(link==vf->links)goto seek_error; /* sign of a bogus stream.
+					       error out, leave
+					       machine uninitialized */
+	vf->current_link=link;
+	
+	ogg_stream_init(&vf->os,vf->current_serialno);
+	ogg_stream_reset(&vf->os); 
+	ogg_stream_init(&work_os,vf->current_serialno);
+	ogg_stream_reset(&work_os); 
+	vf->ready_state=STREAMSET;
+	
+      }
+    
+      ogg_stream_pagein(&vf->os,&og);
+      ogg_stream_pagein(&work_os,&og);
+      eosflag=ogg_page_eos(&og);
     }
   }
-  
+
+  ogg_stream_clear(&work_os);
+  return(0);
+
  seek_error:
   /* dump the machine so we're in a known state */
   vf->pcm_offset=-1;
+  ogg_stream_clear(&work_os);
   _decode_clear(vf);
   return OV_EBADLINK;
 }
@@ -858,9 +966,10 @@
   long ret;
   ogg_int64_t total=ov_pcm_total(vf,-1);
 
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   if(!vf->seekable)return(OV_ENOSEEK);
   if(pos<0 || pos>total)return(OV_EINVAL);
-
+ 
   /* which bitstream section does this pcm offset occur in? */
   for(link=vf->links-1;link>=0;link--){
     total-=vf->pcmlengths[link];
@@ -872,46 +981,117 @@
      missing pages or incorrect frame number information in the
      bitstream could make our task impossible.  Account for that (it
      would be an error condition) */
+
+  /* new search algorithm by HB (Nicholas Vinen) */
   {
     ogg_int64_t target=pos-total;
     long end=vf->offsets[link+1];
     long begin=vf->offsets[link];
+    ogg_int64_t endtime = vf->pcmlengths[link];
+    ogg_int64_t begintime = 0;
     long best=begin;
-
+    
     ogg_page og;
     while(begin<end){
       long bisect;
-    
+      
       if(end-begin<CHUNKSIZE){
         bisect=begin;
       }else{
-	bisect=(end+begin)/2;
+	/* take a (pretty decent) guess. */
+	bisect=begin + 
+	  (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
+	if(bisect<=begin)
+	  bisect=begin+1;
       }
-    
       _seek_helper(vf,bisect);
-      ret=_get_next_page(vf,&og,end-bisect);
-      switch(ret){
-      case OV_FALSE: case OV_EOF:
-	end=bisect;
-	break;
-      case OV_EREAD:
-	goto seek_error;
-      default:
-	{
+    
+      while(begin<end){
+	ret=_get_next_page(vf,&og,end-bisect);
+	if(ret==OV_EREAD) goto seek_error;
+	if(ret<0){
+	  if(bisect<=begin+1)
+	    end=begin; /* found it */
+	  else{
+	    if(bisect==0)goto seek_error;
+	    bisect-=CHUNKSIZE;
+	    if(bisect<=begin)bisect=begin+1;
+	    _seek_helper(vf,bisect);
+	  }
+	}else{
           ogg_int64_t granulepos=ogg_page_granulepos(&og);
           if(granulepos<target){
             best=ret;  /* raw offset of packet with granulepos */ 
-	    begin=vf->offset; /* raw offset of next packet */
+	    begin=vf->offset; /* raw offset of next page */
+	    begintime=granulepos;
+	    
+	    if(target-begin>44100)break;
+	    bisect=begin; /* *not* begin + 1 */
           }else{
-	    end=bisect;
+	    if(bisect<=begin+1)
+	      end=begin;  /* found it */
+	    else{
+	      if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
+		end=ret;
+		bisect-=CHUNKSIZE; /* an endless loop otherwise. */
+		if(bisect<=begin)bisect=begin+1;
+		_seek_helper(vf,bisect);
+	      }else{
+		end=ret;
+		endtime=granulepos;
+		break;
+	      }
+	    }
           }
         }
       }
     }
 
-    /* found our page. seek to it (call raw_seek). */
-    
-    if((ret=ov_raw_seek(vf,best)))goto seek_error;
+    /* found our page. seek to it, update pcm offset. Easier case than
+       raw_seek, don't keep packets preceeding granulepos. */
+    {
+      ogg_page og;
+      ogg_packet op;
+      /* clear out decoding machine state */
+      _decode_clear(vf);  
+      /* seek */
+      _seek_helper(vf,best);
+      
+      if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
+      vf->current_serialno=ogg_page_serialno(&og);
+      vf->current_link=link;
+      
+      ogg_stream_init(&vf->os,vf->current_serialno);
+      ogg_stream_reset(&vf->os); 
+      vf->ready_state=STREAMSET;
+      ogg_stream_pagein(&vf->os,&og);
+
+      /* pull out all but last packet; the one with granulepos */
+      while(1){
+	ret=ogg_stream_packetpeek(&vf->os,&op);
+	if(ret==0){
+	  /* !!! the packet finishing this page originated on a
+             preceeding page. Keep fetching previous pages until we
+             get one with a granulepos or without the 'continued' flag
+             set.  Then just use raw_seek for simplicity. */
+	  while(1){
+	    ret=_get_prev_page(vf,&og);
+	    if(ret<0)goto seek_error;
+	    if(ogg_page_granulepos(&og)>-1 ||
+	       !ogg_page_continued(&og)){
+	      return ov_raw_seek(vf,ret);
+	    }
+	    vf->offset=ret;
+	  }
+	}
+	if(ret<0)goto seek_error;
+	if(op.granulepos!=-1 && !op.e_o_s){
+	  vf->pcm_offset=op.granulepos+total;
+	  break;
+	}else
+	  ret=ogg_stream_packetout(&vf->os,NULL);
+      }
+    }
   }
   
   /* verify result */
@@ -932,11 +1112,71 @@
    returns zero on success, nonzero on failure */
 
 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
+  int thisblock,lastblock=0,blockacc=0;
   int ret=ov_pcm_seek_page(vf,pos);
   if(ret<0)return(ret);
-  
+
+  /* discard leading packets we don't need for the lapping of the
+     position we want; don't decode them */
+#if 0
+  while(1){
+    ogg_packet op;
+    ogg_page og;
+
+    int ret=ogg_stream_packetpeek(&vf->os,&op);
+    if(ret>0){
+      thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
+
+      if(blockacc+
+	 ((lastblock+thisblock)>>2)+
+	 (thisblock>>1)+vf->pcm_offset>pos)break;
+
+      ogg_stream_packetout(&vf->os,NULL);
+      /* end of logical stream case is hard, especially with exact
+         length positioning. */
+
+      if(op.granulepos>-1){
+	int i;
+	/* always believe the stream markers */
+	vf->pcm_offset=op.granulepos;
+	for(i=0;i<vf->current_link;i++)
+	  vf->pcm_offset+=vf->pcmlengths[i];
+	blockacc=0;
+      }else
+	if(lastblock)blockacc+=(lastblock+thisblock)>>2;
+
+      lastblock=thisblock;
+    }else{
+      if(ret<0 && ret!=OV_HOLE)break;
+      
+      /* suck in a new page */
+      if(_get_next_page(vf,&og,-1)<0)break;
+      if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
+      
+      if(vf->ready_state<STREAMSET){
+	int link;
+	
+	vf->current_serialno=ogg_page_serialno(&og);
+	for(link=0;link<vf->links;link++)
+	  if(vf->serialnos[link]==vf->current_serialno)break;
+	if(link==vf->links)return(OV_EBADLINK);
+	vf->current_link=link;
+	
+	ogg_stream_init(&vf->os,vf->current_serialno);
+	ogg_stream_reset(&vf->os); 
+	vf->ready_state=STREAMSET;      
+	lastblock=0;
+      }
+      ogg_stream_pagein(&vf->os,&og);
+    }
+  }
+
+  if(lastblock)vf->pcm_offset+=blockacc;
+#endif
+
   /* discard samples until we reach the desired position. Crossing a
      logical bitstream boundary with abandon is OK. */
+  _make_decode_ready(vf);
   while(vf->pcm_offset<pos){
     float **pcm;
     long target=pos-vf->pcm_offset;
@@ -947,7 +1187,7 @@
     vf->pcm_offset+=samples;
     
     if(samples<target)
-      if(_process_packet(vf,1)==0)
+      if(_process_packet(vf,1)<=0)
         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
   }
   return 0;
@@ -962,6 +1202,7 @@
   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
   double time_total=ov_time_total(vf,-1);
 
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   if(!vf->seekable)return(OV_ENOSEEK);
   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
   
@@ -988,6 +1229,7 @@
   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
   double time_total=ov_time_total(vf,-1);
 
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   if(!vf->seekable)return(OV_ENOSEEK);
   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
   
@@ -1008,11 +1250,13 @@
 /* tell the current stream offset cursor.  Note that seek followed by
    tell will likely not give the set offset due to caching */
 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   return(vf->offset);
 }
 
 /* return PCM offset (sample) of next PCM sample to be read */
 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   return(vf->pcm_offset);
 }
 
@@ -1024,6 +1268,7 @@
   ogg_int64_t pcm_total=0;
   double time_total=0.f;
   
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
   if(vf->seekable){
     pcm_total=ov_pcm_total(vf,-1);
     time_total=ov_time_total(vf,-1);
@@ -1050,20 +1295,17 @@
 vorbis_info *ov_info(OggVorbis_File *vf,int link){
   if(vf->seekable){
     if(link<0)
-      if(vf->decode_ready)
+      if(vf->ready_state>=STREAMSET)
         return vf->vi+vf->current_link;
       else
-	return NULL;
+      return vf->vi;
     else
       if(link>=vf->links)
         return NULL;
       else
         return vf->vi+link;
   }else{
-    if(vf->decode_ready)
-      return vf->vi;
-    else
-      return NULL;
+    return vf->vi;
   }
 }
 
@@ -1071,20 +1313,17 @@
 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
   if(vf->seekable){
     if(link<0)
-      if(vf->decode_ready)
+      if(vf->ready_state>=STREAMSET)
         return vf->vc+vf->current_link;
       else
-	return NULL;
+	return vf->vc;
     else
       if(link>=vf->links)
         return NULL;
       else
         return vf->vc+link;
   }else{
-    if(vf->decode_ready)
-      return vf->vc;
-    else
-      return NULL;
+    return vf->vc;
   }
 }
 
@@ -1117,7 +1356,7 @@
                  word) word size for output.  currently 1 (byte) or 
                        2 (16 bit short)
 
-   return values: <0) error/hole in data (OV_HOLE)
+   return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
                    0) EOF
                    n) number of bytes of PCM actually returned.  The
                    below works on a packet-by-packet basis, so the
@@ -1131,8 +1370,17 @@
   int i,j;
   int host_endian = host_is_big_endian();
 
+  if(vf->ready_state<OPENED)return(OV_EINVAL);
+  if(vf->ready_state==OPENED)return(OV_EOF); /* stream is always
+						initialized after
+						other calls (after
+						open)... unless there
+						was no page at the end
+						to initialize state
+						with. */
+
   while(1){
-    if(vf->decode_ready){
+    if(vf->ready_state>=STREAMSET){
       float **pcm;
       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
       if(samples){

1.2       +1107 -0   vorbis/lib/floor1.c

1.15      +3 -4      vorbis/lib/modes/mode_A.h

Index: mode_A.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_A.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- mode_A.h	2001/02/26 03:51:10	1.14
+++ mode_A.h	2001/05/27 06:44:05	1.15
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_A.h,v 1.14 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_A.h,v 1.15 2001/05/27 06:44:05 xiphmont Exp $
 
  ********************************************************************/
 
@@ -109,6 +109,7 @@
   .5f,   /* high window */
   5,
   5,
+  10,
   {.000f, 0.f,/*63*/
    .000f, 0.f,/*88*/
    .000f, 0.f,/*125*/
@@ -132,7 +133,6 @@
             tight loop) */
   -22.,
 
-  -0., -.004   /* attack/decay control */
 };
 
 static vorbis_info_psy _psy_set_A={
@@ -199,6 +199,7 @@
   .5f,   /* high window */
   25,
   25,
+  50,
   {.000f, 0.f, /*63*/
    .000f, 0.f, /*88*/
    .000f, 0.f, /*125*/
@@ -221,8 +222,6 @@
   95.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -28.,
-
-  -0.f, -.004f,   /* attack/decay control */
 
 };
 

1.11      +3 -5      vorbis/lib/modes/mode_AA.h

Index: mode_AA.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_AA.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- mode_AA.h	2001/02/26 03:51:10	1.10
+++ mode_AA.h	2001/05/27 06:44:05	1.11
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_AA.h,v 1.10 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_AA.h,v 1.11 2001/05/27 06:44:05 xiphmont Exp $
 
  ********************************************************************/
 
@@ -109,6 +109,7 @@
   .5f,   /* high window */
   5,
   5,
+  10,
   {.000f, 0.f,/*63*/
    .000f, 0.f,/*88*/
    .000f, 0.f,/*125*/
@@ -131,8 +132,6 @@
   95.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -22.,
-
-  -0., -.004   /* attack/decay control */
 };
 
 static vorbis_info_psy _psy_set_AA={
@@ -199,6 +198,7 @@
   .7f,   /* high window */
   25,
   25,
+  50,
   {.000f, 0.f, /*63*/
    .000f, 0.f, /*88*/
    .000f, 0.f, /*125*/
@@ -221,8 +221,6 @@
   95.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -22.,
-
-  -0.f, -.004f,   /* attack/decay control */
 
 };
 

1.14      +3 -5      vorbis/lib/modes/mode_B.h

Index: mode_B.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_B.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- mode_B.h	2001/02/26 03:51:10	1.13
+++ mode_B.h	2001/05/27 06:44:05	1.14
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_B.h,v 1.13 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_B.h,v 1.14 2001/05/27 06:44:05 xiphmont Exp $
 
  ********************************************************************/
 
@@ -109,6 +109,7 @@
   .5f,   /* high window */
   5,
   5,
+  10,
   {.000f, 0.f,/*63*/
    .000f, 0.f,/*88*/
    .000f, 0.f,/*125*/
@@ -131,8 +132,6 @@
    95.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -26.,
-
-  -0., -.004   /* attack/decay control */
 };
 
 static vorbis_info_psy _psy_set_B={
@@ -199,6 +198,7 @@
   .5f,   /* high window */
   25,
   25,
+  40,
   {.000f, 0.f, /*63*/
    .000f, 0.f, /*88*/
    .000f, 0.f, /*125*/
@@ -221,8 +221,6 @@
   105.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -30.,
-
-  -0.f, -.004f,   /* attack/decay control */
 
 };
 

1.13      +3 -5      vorbis/lib/modes/mode_C.h

Index: mode_C.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_C.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- mode_C.h	2001/02/26 03:51:10	1.12
+++ mode_C.h	2001/05/27 06:44:05	1.13
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_C.h,v 1.12 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_C.h,v 1.13 2001/05/27 06:44:05 xiphmont Exp $
 
  ********************************************************************/
 
@@ -109,6 +109,7 @@
   .5f,   /* high window */
   5,
   5,
+  10,
   {.000f, 0.f,/*63*/
    .000f, 0.f,/*88*/
    .000f, 0.f,/*125*/
@@ -131,8 +132,6 @@
   105.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -26.,
-
-  -0., -.004   /* attack/decay control */
 };
 
 static vorbis_info_psy _psy_set_C={
@@ -199,6 +198,7 @@
   .5f,   /* high window */
   25,
   25,
+  40,
   {.000f, 0.f, /*63*/
    .000f, 0.f, /*88*/
    .000f, 0.f, /*125*/
@@ -221,8 +221,6 @@
   105.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -32.,
-
-  -0.f, -.004f,   /* attack/decay control */
 
 };
 

1.14      +3 -5      vorbis/lib/modes/mode_D.h

Index: mode_D.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_D.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- mode_D.h	2001/02/26 03:51:10	1.13
+++ mode_D.h	2001/05/27 06:44:05	1.14
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_D.h,v 1.13 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_D.h,v 1.14 2001/05/27 06:44:05 xiphmont Exp $
 
  ********************************************************************/
 
@@ -107,6 +107,7 @@
   .5f,   /* high window */
   5,
   5,
+  10,
   {.000f, 0.f,/*63*/
    .000f, 0.f,/*88*/
    .000f, 0.f,/*125*/
@@ -129,8 +130,6 @@
   105.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -28.,
-
-  -0., -.004   /* attack/decay control */
 };
 
 static vorbis_info_psy _psy_set_D={
@@ -197,6 +196,7 @@
   .5f,   /* high window */
   25,
   25,
+  40,
   {.000f, 0.f, /*63*/
    .000f, 0.f, /*88*/
    .000f, 0.f, /*125*/
@@ -219,8 +219,6 @@
   105.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -32.,
-
-  -0.f, -.004f,   /* attack/decay control */
 
 };
 

1.13      +3 -5      vorbis/lib/modes/mode_E.h

Index: mode_E.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/modes/mode_E.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- mode_E.h	2001/02/26 03:51:10	1.12
+++ mode_E.h	2001/05/27 06:44:05	1.13
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_E.h,v 1.12 2001/02/26 03:51:10 xiphmont Exp $
+ last mod: $Id: mode_E.h,v 1.13 2001/05/27 06:44:05 xiphmont Exp $
 
  ********************************************************************/
 
@@ -107,13 +107,12 @@
   .5f,   /* high window */
   5,
   5,
+  10,
   {0.f},
  
   105.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -28.,
-
-  -0., -.004   /* attack/decay control */
 };
 
 static vorbis_info_psy _psy_set_E={
@@ -180,13 +179,12 @@
   .5f,   /* high window */
   25,
   25,
+  40,
   {0.f},
  
   105.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
   -32.,
-
-  -0.f, -.004f,   /* attack/decay control */
 
 };
 

1.24      +3 -3      vorbis/vq/bookutil.c

Index: bookutil.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/vq/bookutil.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- bookutil.c	2001/02/26 03:51:12	1.23
+++ bookutil.c	2001/05/27 06:44:07	1.24
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: utility functions for loading .vqh and .vqd files
- last mod: $Id: bookutil.c,v 1.23 2001/02/26 03:51:12 xiphmont Exp $
+ last mod: $Id: bookutil.c,v 1.24 2001/05/27 06:44:07 xiphmont Exp $
 
  ********************************************************************/
 
@@ -191,7 +191,7 @@
   }
 
   /* find the codebook struct */
-  find_seek_to(in,"static static_codebook _vq_book_");
+  find_seek_to(in,"static static_codebook _");
 
   /* get the major important values */
   line=get_line(in);
@@ -379,7 +379,7 @@
     }
   
   /* load the lengthlist */
-  find_seek_to(in,"static long _vq_lengthlist");
+  find_seek_to(in,"_lengthlist");
   reset_next_value();
   c->lengthlist=_ogg_malloc(sizeof(long)*c->entries);
   for(i=0;i<c->entries;i++)

1.5       +3 -3      vorbis/vq/distribution.c

Index: distribution.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/vq/distribution.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- distribution.c	2001/02/26 03:51:12	1.4
+++ distribution.c	2001/05/27 06:44:07	1.5
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: utility for finding the distribution in a data set
- last mod: $Id: distribution.c,v 1.4 2001/02/26 03:51:12 xiphmont Exp $
+ last mod: $Id: distribution.c,v 1.5 2001/05/27 06:44:07 xiphmont Exp $
 
  ********************************************************************/
 
@@ -155,7 +155,7 @@
         flag=1;
       }
       
-      while(sscanf(line,"%f",&code)==1){
+      while(line && sscanf(line,"%f",&code)==1){
         line=strchr(line,',');
         if(line)line++;
         if(code<min)min=code;
@@ -187,7 +187,7 @@
       lines--;
       if(!(lines&0xff))spinnit("counting distribution. lines so far...",lines);
       
-      while(sscanf(line,"%f",&code)==1){
+      while(line && sscanf(line,"%f",&code)==1){
         line=strchr(line,',');
         if(line)line++;
         

1.9       +53 -34    vorbis/vq/huffbuild.c

Index: huffbuild.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/vq/huffbuild.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- huffbuild.c	2001/02/26 03:51:12	1.8
+++ huffbuild.c	2001/05/27 06:44:07	1.9
@@ -7,11 +7,11 @@
  *                                                                  *
  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
-
+ *                                                                  *
  ********************************************************************
 
  function: hufftree builder
- last mod: $Id: huffbuild.c,v 1.8 2001/02/26 03:51:12 xiphmont Exp $
+ last mod: $Id: huffbuild.c,v 1.9 2001/05/27 06:44:07 xiphmont Exp $
 
  ********************************************************************/
 
@@ -50,7 +50,7 @@
 static void usage(){
   fprintf(stderr,
           "usage:\n" 
-	  "huffbuild <input>.vqd <begin,n,group> [noguard]\n"
+	  "huffbuild <input>.vqd <begin,n,group>|<lorange-hirange> [noguard]\n"
           "   where begin,n,group is first scalar, \n"
           "                          number of scalars of each in line,\n"
           "                          number of scalars in a group\n"
@@ -65,6 +65,7 @@
   int i,j,k,begin,n,subn,guard=1;
   FILE *file;
   int maxval=0;
+  int loval=0;
 
   if(argc<3)usage();
   if(argc==4)guard=0;
@@ -76,19 +77,28 @@
 
   {
     char *pos=strchr(argv[2],',');
-    begin=atoi(argv[2]);
-    if(!pos)
-      usage();
-    else
-      n=atoi(pos+1);
-    pos=strchr(pos+1,',');
-    if(!pos)
-      usage();
-    else
-      subn=atoi(pos+1);
-    if(n/subn*subn != n){
-      fprintf(stderr,"n must be divisible by group\n");
-      exit(1);
+    char *dpos=strchr(argv[2],'-');
+    if(dpos){
+      loval=atoi(argv[2]);
+      maxval=atoi(dpos+1);
+      subn=1;
+      subn=1;
+      begin=0;
+    }else{
+      begin=atoi(argv[2]);
+      if(!pos)
+	usage();
+      else
+	n=atoi(pos+1);
+      pos=strchr(pos+1,',');
+      if(!pos)
+	usage();
+      else
+	subn=atoi(pos+1);
+      if(n/subn*subn != n){
+	fprintf(stderr,"n must be divisible by group\n");
+	exit(1);
+      }
     }
   }
 
@@ -96,35 +106,44 @@
   file=fopen(infile,"r");
   if(!file){
     fprintf(stderr,"Could not open file %s\n",infile);
-    exit(1);
+    if(!maxval)
+      exit(1);
+    else
+      fprintf(stderr,"  making untrained books.\n");
+
   }
-  i=0;
-  while(1){
-    long v;
-    if(get_next_ivalue(file,&v))break;
-    if(v>maxval)maxval=v;
 
-    if(!(i++&0xff))spinnit("loading... ",i);
+  if(!maxval){
+    i=0;
+    while(1){
+      long v;
+      if(get_next_ivalue(file,&v))break;
+      if(v>maxval)maxval=v;
+      
+      if(!(i++&0xff))spinnit("loading... ",i);
+    }
+    rewind(file);
+    maxval++;
   }
-  rewind(file);
-  maxval++;
 
   {
     long vals=pow(maxval,subn);
     long *hist=_ogg_malloc(vals*sizeof(long));
     long *lengths=_ogg_malloc(vals*sizeof(long));
     
-    for(j=0;j<vals;j++)hist[j]=guard;
+    for(j=loval;j<vals;j++)hist[j]=guard;
     
-    reset_next_value();
-    i/=subn;
-    while(!feof(file)){
-      long val=getval(file,begin,n,subn,maxval);
-      if(val==-1)break;
-      hist[val]++;
-      if(!(i--&0xff))spinnit("loading... ",i*subn);
+    if(file){
+      reset_next_value();
+      i/=subn;
+      while(!feof(file)){
+	long val=getval(file,begin,n,subn,maxval);
+	if(val==-1 || val>=maxval)break;
+	hist[val]++;
+	if(!(i--&0xff))spinnit("loading... ",i*subn);
+      }
+      fclose(file);
     }
-    fclose(file);
  
     /* we have the probabilities, build the tree */
     fprintf(stderr,"Building tree for %ld entries\n",vals);

1.9       +2 -2      vorbis/vq/latticehint.c

Index: latticehint.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/vq/latticehint.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- latticehint.c	2001/02/26 03:51:12	1.8
+++ latticehint.c	2001/05/27 06:44:07	1.9
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: utility main for building thresh/pigeonhole encode hints
- last mod: $Id: latticehint.c,v 1.8 2001/02/26 03:51:12 xiphmont Exp $
+ last mod: $Id: latticehint.c,v 1.9 2001/05/27 06:44:07 xiphmont Exp $
 
  ********************************************************************/
 
@@ -186,7 +186,7 @@
       if(dB){
         if(fabs(v1)<.01)v1=(v1+v2)*.5;
         if(fabs(v2)<.01)v2=(v1+v2)*.5;
-	t->quantthresh[i]=fromdB((todB(v1)+todB(v2))*.5);
+	t->quantthresh[i]=fromdB((todB(&v1)+todB(&v2))*.5);
         if(v1<0 || v2<0)t->quantthresh[i]*=-1;
 
       }else{

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list