[xiph-cvs] cvs commit: vorbis/lib analysis.c block.c codebook.c floor0.c floor1.c info.c mapping0.c psy.c psytune.c registry.c res0.c synthesis.c time0.c backends.h codec_internal.h psy.h registry.h

Monty xiphmont at xiph.org
Wed Aug 1 23:14:49 PDT 2001



xiphmont    01/08/01 23:14:48

  Modified:    lib      Tag: branch_monty_20010708 analysis.c block.c
                        codebook.c floor0.c floor1.c info.c mapping0.c
                        psy.c psytune.c registry.c res0.c synthesis.c
                        time0.c backends.h codec_internal.h psy.h
                        registry.h
  Log:
  multiple coupling/quantization pass engine in place for CBR/ABR/BBR.
  Of course, I haven't typed 'make' yet...

Revision  Changes    Path
No                   revision

No                   revision

1.44.2.1  +2 -1      vorbis/lib/analysis.c

Index: analysis.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/analysis.c,v
retrieving revision 1.44
retrieving revision 1.44.2.1
diff -u -r1.44 -r1.44.2.1
--- analysis.c	2001/05/27 06:43:59	1.44
+++ analysis.c	2001/08/02 06:14:42	1.44.2.1
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: single-block PCM analysis mode dispatch
- last mod: $Id: analysis.c,v 1.44 2001/05/27 06:43:59 xiphmont Exp $
+ last mod: $Id: analysis.c,v 1.44.2.1 2001/08/02 06:14:42 xiphmont Exp $
 
  ********************************************************************/
 
@@ -20,6 +20,7 @@
 #include <math.h>
 #include <ogg/ogg.h>
 #include "vorbis/codec.h"
+#include "codec_internal.h"
 #include "registry.h"
 #include "scales.h"
 #include "os.h"

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

Index: block.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/block.c,v
retrieving revision 1.48.2.1
retrieving revision 1.48.2.2
diff -u -r1.48.2.1 -r1.48.2.2
--- block.c	2001/07/08 08:48:01	1.48.2.1
+++ block.c	2001/08/02 06:14:42	1.48.2.2
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.48.2.1 2001/07/08 08:48:01 xiphmont Exp $
+ last mod: $Id: block.c,v 1.48.2.2 2001/08/02 06:14:42 xiphmont Exp $
 
  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
  more amusing by Vorbis' current two allowed block sizes.
@@ -406,7 +406,7 @@
 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
   vorbis_info *vi=v->vi;
   codec_setup_info *ci=vi->codec_setup;
-  backend_lookup_state *b=v->backend_state;
+  /*backend_lookup_state *b=v->backend_state;*/
 
   if(vals<=0){
     int order=32;

1.27.2.1  +2 -2      vorbis/lib/codebook.c

Index: codebook.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/codebook.c,v
retrieving revision 1.27
retrieving revision 1.27.2.1
diff -u -r1.27 -r1.27.2.1
--- codebook.c	2001/06/18 22:19:26	1.27
+++ codebook.c	2001/08/02 06:14:43	1.27.2.1
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: basic codebook pack/unpack/code/decode operations
- last mod: $Id: codebook.c,v 1.27 2001/06/18 22:19:26 xiphmont Exp $
+ last mod: $Id: codebook.c,v 1.27.2.1 2001/08/02 06:14:43 xiphmont Exp $
 
  ********************************************************************/
 
@@ -424,7 +424,7 @@
     entry = vorbis_book_decode(book,b);
     if(entry==-1)return(-1);
     {
-      const float *t     = book->valuelist+entry*book->dim;
+      const float *t = book->valuelist+entry*book->dim;
       for (j=0;j<book->dim;j++){
         a[chptr++][i]+=t[j];
         if(chptr==ch){

1.43.2.2  +4 -8      vorbis/lib/floor0.c

Index: floor0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/floor0.c,v
retrieving revision 1.43.2.1
retrieving revision 1.43.2.2
diff -u -r1.43.2.1 -r1.43.2.2
--- floor0.c	2001/07/08 08:48:01	1.43.2.1
+++ floor0.c	2001/08/02 06:14:43	1.43.2.2
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: floor backend 0 implementation
- last mod: $Id: floor0.c,v 1.43.2.1 2001/07/08 08:48:01 xiphmont Exp $
+ last mod: $Id: floor0.c,v 1.43.2.2 2001/08/02 06:14:43 xiphmont Exp $
 
  ********************************************************************/
 
@@ -258,9 +258,9 @@
 }
 
 static int floor0_forward(vorbis_block *vb,vorbis_look_floor *in,
-			  const float *mdct, const float *logmdct,   /* in */
+			  float *mdct, const float *logmdct,   /* in */
                           const float *logmask, const float *logmax, /* in */
-			  float *residue, float *codedflr){          /* out */
+			  float *codedflr){          /* out */
   long j;
   vorbis_look_floor0 *look=(vorbis_look_floor0 *)in;
   vorbis_info_floor0 *info=look->vi;
@@ -397,10 +397,6 @@
     _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);
   }
 
@@ -409,7 +405,7 @@
 #endif
 
   memset(codedflr,0,sizeof(float)*look->n);
-  memset(residue,0,sizeof(float)*look->n);
+  memset(mdct,0,sizeof(float)*look->n);
   return(val);
 }
 

1.10.2.2  +93 -86    vorbis/lib/floor1.c

Index: floor1.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/floor1.c,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.2
diff -u -r1.10.2.1 -r1.10.2.2
--- floor1.c	2001/07/08 08:48:01	1.10.2.1
+++ floor1.c	2001/08/02 06:14:43	1.10.2.2
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: floor backend 1 implementation
- last mod: $Id: floor1.c,v 1.10.2.1 2001/07/08 08:48:01 xiphmont Exp $
+ last mod: $Id: floor1.c,v 1.10.2.2 2001/08/02 06:14:43 xiphmont Exp $
 
  ********************************************************************/
 
@@ -621,9 +621,9 @@
 }
 
 static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
-			  const float *mdct, const float *logmdct,   /* in */
+			  float *mdct, const float *logmdct,   /* in */
                           const float *logmask, const float *logmax, /* in */
-			  float *residue, float *codedflr){          /* out */
+			  float *codedflr){          /* out */
   static int seq=0;
   long i,j,k,l;
   vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
@@ -641,9 +641,15 @@
   int memo[VIF_POSIT+2];
   codec_setup_info *ci=vb->vd->vi->codec_setup;
   static_codebook **sbooks=ci->book_param;
-  codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
-    fullbooks;   
+  codebook *books=NULL;
+  int writeflag=0;
 
+  if(vb->vd->backend_state){
+    books=((backend_lookup_state *)(vb->vd->backend_state))->
+      fullbooks;   
+    writeflag=1;
+  }
+
   memset(fit_flag,0,sizeof(fit_flag));
   for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
   for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
@@ -884,97 +890,99 @@
 
     /* we have everything we need. pack it out */
     /* mark nontrivial floor */
-    oggpack_write(&vb->opb,1,1);
-
-    /* beginning/end post */
-    look->frames++;
-    look->postbits+=ilog(look->quant_q-1)*2;
-    oggpack_write(&vb->opb,fit_valueA[0],ilog(look->quant_q-1));
-    oggpack_write(&vb->opb,fit_valueA[1],ilog(look->quant_q-1));
-
+    if(writeflag){
+      oggpack_write(&vb->opb,1,1);
+      
+      /* beginning/end post */
+      look->frames++;
+      look->postbits+=ilog(look->quant_q-1)*2;
+      oggpack_write(&vb->opb,fit_valueA[0],ilog(look->quant_q-1));
+      oggpack_write(&vb->opb,fit_valueA[1],ilog(look->quant_q-1));
+      
 #ifdef TRAIN_FLOOR1
-    {
-      FILE *of;
-      char buffer[80];
-      sprintf(buffer,"line%d_full.vqd",vb->mode);
-      of=fopen(buffer,"a");
-      for(j=2;j<posts;j++)
-	fprintf(of,"%d\n",fit_valueB[j]);
-      fclose(of);
-    }
+      {
+	FILE *of;
+	char buffer[80];
+	sprintf(buffer,"line%d_full.vqd",vb->mode);
+	of=fopen(buffer,"a");
+	for(j=2;j<posts;j++)
+	  fprintf(of,"%d\n",fit_valueB[j]);
+	fclose(of);
+      }
 #endif
-
-    
-    /* partition by partition */
-    for(i=0,j=2;i<info->partitions;i++){
-      int class=info->partitionclass[i];
-      int cdim=info->class_dim[class];
-      int csubbits=info->class_subs[class];
-      int csub=1<<csubbits;
-      int bookas[8]={0,0,0,0,0,0,0,0};
-      int cval=0;
-      int cshift=0;
-
-      /* generate the partition's first stage cascade value */
-      if(csubbits){
-	int maxval[8];
-	for(k=0;k<csub;k++){
-	  int booknum=info->class_subbook[class][k];
-	  if(booknum<0){
-	    maxval[k]=1;
-	  }else{
-	    maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
+      
+      
+      /* partition by partition */
+      for(i=0,j=2;i<info->partitions;i++){
+	int class=info->partitionclass[i];
+	int cdim=info->class_dim[class];
+	int csubbits=info->class_subs[class];
+	int csub=1<<csubbits;
+	int bookas[8]={0,0,0,0,0,0,0,0};
+	int cval=0;
+	int cshift=0;
+	
+	/* generate the partition's first stage cascade value */
+	if(csubbits){
+	  int maxval[8];
+	  for(k=0;k<csub;k++){
+	    int booknum=info->class_subbook[class][k];
+	    if(booknum<0){
+	      maxval[k]=1;
+	    }else{
+	      maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
+	    }
           }
-	}
-	for(k=0;k<cdim;k++){
-	  for(l=0;l<csub;l++){
-	    int val=fit_valueB[j+k];
-	    if(val<maxval[l]){
-	      bookas[k]=l;
-	      break;
+	  for(k=0;k<cdim;k++){
+	    for(l=0;l<csub;l++){
+	      int val=fit_valueB[j+k];
+	      if(val<maxval[l]){
+		bookas[k]=l;
+		break;
+	      }
             }
+	    cval|= bookas[k]<<cshift;
+	    cshift+=csubbits;
           }
-	  cval|= bookas[k]<<cshift;
-	  cshift+=csubbits;
-	}
-	/* write it */
-	look->phrasebits+=
+	  /* write it */
+	  look->phrasebits+=
           vorbis_book_encode(books+info->class_book[class],cval,&vb->opb);
-
-#ifdef TRAIN_FLOOR1
-	{
-	  FILE *of;
-	  char buffer[80];
-	  sprintf(buffer,"line%d_class%d.vqd",vb->mode,class);
-	  of=fopen(buffer,"a");
-	  fprintf(of,"%d\n",cval);
-	  fclose(of);
-	}
-#endif
-      }
-      
-      /* write post values */
-      for(k=0;k<cdim;k++){
-	int book=info->class_subbook[class][bookas[k]];
-	if(book>=0){
-	  look->postbits+=vorbis_book_encode(books+book,
-			     fit_valueB[j+k],&vb->opb);
-
+	  
 #ifdef TRAIN_FLOOR1
           {
             FILE *of;
             char buffer[80];
-	    sprintf(buffer,"line%d_%dsub%d.vqd",vb->mode,class,bookas[k]);
+	    sprintf(buffer,"line%d_class%d.vqd",vb->mode,class);
             of=fopen(buffer,"a");
-	    fprintf(of,"%d\n",fit_valueB[j+k]);
+	    fprintf(of,"%d\n",cval);
             fclose(of);
           }
 #endif
         }
+	
+	/* write post values */
+	for(k=0;k<cdim;k++){
+	  int book=info->class_subbook[class][bookas[k]];
+	  if(book>=0){
+	    look->postbits+=vorbis_book_encode(books+book,
+					       fit_valueB[j+k],&vb->opb);
+	    
+#ifdef TRAIN_FLOOR1
+	    {
+	      FILE *of;
+	      char buffer[80];
+	      sprintf(buffer,"line%d_%dsub%d.vqd",vb->mode,class,bookas[k]);
+	      of=fopen(buffer,"a");
+	      fprintf(of,"%d\n",fit_valueB[j+k]);
+	      fclose(of);
+	    }
+#endif
+	  }
+	}
+	j+=cdim;
       }
-      j+=cdim;
     }
-    
+
     {
       /* generate quantized floor equivalent to what we'd unpack in decode */
       int hx;
@@ -995,25 +1003,24 @@
       }
       for(j=lx;j<vb->pcmend/2;j++)codedflr[j]=codedflr[j-1]; /* be certain */
 
-      /* use it to create residue vector.  Eliminate residue elements
+      /* use it to create residue vector.  Eliminate mdct elements
          that were below the error training attenuation relative to
          the original mask.  This avoids portions of the floor fit
          that were considered 'unused' in fitting from being used in
          coding residue if the unfit values are significantly below
          the original input mask */
+
       for(j=0;j<n;j++)
         if(logmdct[j]+info->twofitatten<logmask[j])
-	  residue[j]=0.f;
-	else
-	  residue[j]=mdct[j]/codedflr[j];
-      for(j=n;j<vb->pcmend/2;j++)residue[j]=0.f;
+	  mdct[j]=0.f;
+      for(j=n;j<vb->pcmend/2;j++)mdct[j]=0.f;
 
     }    
 
   }else{
-    oggpack_write(&vb->opb,0,1);
+    if(writeflag)oggpack_write(&vb->opb,0,1);
     memset(codedflr,0,n*sizeof(float));
-    memset(residue,0,n*sizeof(float));
+    memset(mdct,0,n*sizeof(float));
   }
   seq++;
   return(nonzero);

1.41.2.1  +1 -2      vorbis/lib/info.c

Index: info.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/info.c,v
retrieving revision 1.41
retrieving revision 1.41.2.1
diff -u -r1.41 -r1.41.2.1
--- info.c	2001/06/15 21:15:39	1.41
+++ info.c	2001/08/02 06:14:43	1.41.2.1
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: maintain the info structure, info <-> header packets
- last mod: $Id: info.c,v 1.41 2001/06/15 21:15:39 xiphmont Exp $
+ last mod: $Id: info.c,v 1.41.2.1 2001/08/02 06:14:43 xiphmont Exp $
 
  ********************************************************************/
 
@@ -23,7 +23,6 @@
 #include <ctype.h>
 #include <ogg/ogg.h>
 #include "vorbis/codec.h"
-#include "backends.h"
 #include "codec_internal.h"
 #include "codebook.h"
 #include "registry.h"

1.33.2.3  +175 -127  vorbis/lib/mapping0.c

Index: mapping0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/mapping0.c,v
retrieving revision 1.33.2.2
retrieving revision 1.33.2.3
diff -u -r1.33.2.2 -r1.33.2.3
--- mapping0.c	2001/07/11 05:23:22	1.33.2.2
+++ mapping0.c	2001/08/02 06:14:43	1.33.2.3
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.33.2.2 2001/07/11 05:23:22 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.33.2.3 2001/08/02 06:14:43 xiphmont Exp $
 
  ********************************************************************/
 
@@ -81,16 +81,17 @@
       l->time_func[i]->free_look(l->time_look[i]);
       l->floor_func[i]->free_look(l->floor_look[i]);
       l->residue_func[i]->free_look(l->residue_look[i]);
-      if(l->psy_look)_vp_psy_clear(l->psy_look+i);
     }
-
+    if(l->psy_look){
+      _vp_psy_clear(l->psy_look);
+      _ogg_free(l->psy_look);
+    }
     _ogg_free(l->time_func);
     _ogg_free(l->floor_func);
     _ogg_free(l->residue_func);
     _ogg_free(l->time_look);
     _ogg_free(l->floor_look);
     _ogg_free(l->residue_look);
-    if(l->psy_look)_ogg_free(l->psy_look);
     memset(l,0,sizeof(vorbis_look_mapping0));
     _ogg_free(l);
   }
@@ -109,7 +110,7 @@
   look->floor_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_floor *));
 
   look->residue_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_residue *));
-  if(ci->psys)look->psy_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_psy));
+  if(ci->psys)look->psy_look=_ogg_calloc(1,sizeof(vorbis_look_psy));
 
   look->time_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_time *));
   look->floor_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_floor *));
@@ -130,12 +131,12 @@
     look->residue_look[i]=look->residue_func[i]->
       look(vd,vm,ci->residue_param[resnum]);
     
-    if(ci->psys && vd->analysisp){
-      int psynum=info->psysubmap[i];
-      _vp_psy_init(look->psy_look+i,ci->psy_param[psynum],
-		   ci->psy_g_param,
-		   ci->blocksizes[vm->blockflag]/2,vi->rate);
-    }
+  }
+  if(ci->psys && vd->analysisp){
+    int psynum=info->psy;;
+    _vp_psy_init(look->psy_look,ci->psy_param[psynum],
+		 ci->psy_g_param,
+		 ci->blocksizes[vm->blockflag]/2,vi->rate);
   }
 
   look->ch=vi->channels;
@@ -269,30 +270,26 @@
   int                    n=vb->pcmend;
   int i,j;
   float *window=b->window[vb->W][vb->lW][vb->nW][mode->windowtype];
+  int   *nonzero=alloca(sizeof(int)*vi->channels);
 
-  float **pcmbundle=alloca(sizeof(float *)*vi->channels);
-  int    *zerobundle=alloca(sizeof(int)*vi->channels);
-
-  int    *nonzero=alloca(sizeof(int)*vi->channels);
-
   float *work=_vorbis_block_alloc(vb,n*sizeof(float));
-  float newmax=vbi->ampmax;
+
+  float global_ampmax=vbi->ampmax;
+  float *local_ampmax=alloca(sizeof(float)*vi->channels);
 
   for(i=0;i<vi->channels;i++){
     float scale=4.f/n;
-    int submap=info->chmuxlist[i];
-    float ret;
 
     /* 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 *logfft  =pcm+n/2;
+
+    /*float *res     =pcm;
+    float *codedflr=pcm+n/2;
     float *logmax  =work;
-    float *logmask =work+n/2;
+    float *logmask =work+n/2;*/
 
     /* window the PCM data */
     for(j=0;j<n;j++)
@@ -301,31 +298,50 @@
     /* 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,fft);
     fft[0]*=scale;
-    fft[0]=todB(fft);
+    logfft[0]=todB(fft);
+    local_ampmax[i]=logfft[0];
     for(j=1;j<n-1;j+=2){
       float temp=scale*FAST_HYPOT(fft[j],fft[j+1]);
-      logfft[(j+1)>>1]=todB(&temp);
+      temp=logfft[(j+1)>>1]=todB(&temp);
+      if(temp>local_ampmax[i])local_ampmax[i]=temp;
     }
+    if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
+
+    _analysis_output("fft",seq+i,logfft,n/2,1,0);
+  }
 
-    _analysis_output("fft",seq,logfft,n/2,1,0);
+  for(i=0;i<vi->channels;i++){
+    int submap=info->chmuxlist[i];
+
+    /* the following makes things clearer to *me* anyway */
+    float *mdct    =vb->pcm[i]; 
+    float *res     =mdct;
+    float *codedflr=mdct+n/2;
+    float *logfft  =mdct+n/2;
+
+    float *logmdct =work;
+    float *logmax  =mdct+n/2;
+    float *logmask =work+n/2;
+
+    for(j=0;j<n/2;j++)
+      logmdct[j]=todB(mdct+j);
     _analysis_output("mdct",seq,logmdct,n/2,1,0);
 
+
     /* perform psychoacoustics; do masking */
-    ret=_vp_compute_mask(look->psy_look+submap,
-			 b->psy_g_look,
-			 i,
-			 logfft, /* -> logmax */
-			 logmdct,
-			 logmask,
-			 vbi->ampmax,
-			 ci->blocksizes[vb->lW]/2);
-    if(ret>newmax)newmax=ret;
+    _vp_compute_mask(look->psy_look,
+		     b->psy_g_look,
+		     i,
+		     logfft, /* -> logmax */
+		     logmdct,
+		     logmask,
+		     global_ampmax,
+		     local_ampmax[i],
+		     ci->blocksizes[vb->lW]/2);
 
     _analysis_output("mask",seq,logmask,n/2,1,0);
     
@@ -336,110 +352,142 @@
               logmdct,
               logmask,
               logmax,
-	      res,
+
               codedflr);
+
 
-    /*for(j=0;j<n/2;j++)
-      if(fabs(vb->pcm[i][j]>200))
-      fprintf(stderr,"%ld ",seq);*/
+    _vp_remove_floor(look->psy_look,
+		     b->psy_g_look,
+		     logmdct,
+		     mdct,
+		     codedflr,
+		     res,
+		     local_ampmax[i]);
+
+    for(j=0;j<n/2;j++)
+      if(fabs(vb->pcm[i][j])>1500)
+	fprintf(stderr,"%ld ",seq);
     
-    _analysis_output("res",seq,vb->pcm[i],n,1,0);
+    _analysis_output("res",seq,res,n,1,0);
     _analysis_output("codedflr",seq++,codedflr,n/2,1,1);
       
   }
 
-  vbi->ampmax=newmax;
+  vbi->ampmax=global_ampmax;
 
-  /* channel coupling */
-  for(i=0;i<info->coupling_steps;i++){
-    if(nonzero[info->coupling_mag[i]] ||
-       nonzero[info->coupling_ang[i]]){
-      
-      float *pcmM=vb->pcm[info->coupling_mag[i]];
-      float *pcmA=vb->pcm[info->coupling_ang[i]];
-      
-    /*     +- 
-            B
-            |       A-B
-     -4 -3 -2 -1  0                    
-            |
-      3     |     1
-            |
-  -+  2-----+-----2----A ++  
-            |
-      1     |     3
-            |
-      0 -1 -2 -3 -4
-  B-A       |
-           --
-
-    */
-
-      nonzero[info->coupling_mag[i]]=1; 
-      nonzero[info->coupling_ang[i]]=1; 
-
-      for(j=n/2-1;j>=0;j--){
-	float A=rint(pcmM[j]);
-	float B=rint(pcmA[j]);
-	float mag;
-	float ang;
-	
-	if(fabs(A)>fabs(B)){
-	  mag=A;
-	  if(A>0)
-	    ang=A-B;
-	  else
-	    ang=B-A;
-	}else{
-	  mag=B;
-	  if(B>0)
-	    ang=A-B;
-	  else
-	    ang=B-A;
-	}
-	
-	if(j>12){
-	  
-	  if(j>=n*3/64){
-	    
-	    if(j>=n*3/32){
-	      ang=0;
-	    }else{
-	      if(mag!=0.f)ang=rint(ang/mag)*mag;
-	      //if(fabs(mag)<2.5)
-	      //ang=0;
-	    }
-	  }
-	}
+  /* partition based prequantization and channel coupling */
+  /* Steps in prequant and coupling:
+     
+     down-couple/down-quantize from perfect residue ->  quantized vector 
+     classify by this first quantized vector
+     
+     do{ 
+        encode quantized vector; add encoded values to 'so-far' vector
+        more? [not yet at bitrate/not yet at target]
+          yes{
+              down-couple/down-quantize from perfect-'so-far' -> 
+	        quantized vector; when subtracting coupling, 
+		account for +/- out-of-phase component
+          }no{  
+              break
+          }
+     }
+     done.
+
+     quantization in each iteration is done (after circular normalization 
+     in coupling) using a by-iteration quantization granule value.
+  */
+   
+  {
+    float  **pcm=vb->pcm;
+    float  **quantized=alloca(sizeof(float*)*vi->channels);
+    float  **sofar=alloca(sizeof(float*)*vi->channels);
+
+    long  ***classifications=alloca(sizeof(long**)*info->submaps);
+    float ***pcmbundle=alloca(sizeof(float **)*info->submaps);
+    int    **zerobundle=alloca(sizeof(int *)*info->submaps);
+    int     *chbundle=alloca(sizeof(int)*info->submaps);
+    int      chcounter=0;
+
+    /* play a little loose with this abstraction */
+    int   quant_passes=look->psy_look->vi->coupling_passes;
+    int   stopflag=0;
 
+    for(i=0;i<vi->channels;i++){
+      quantized[i]=perfect[i]+n/2;
+      sofar[i]=_vorbis_block_alloc(vb,n/2*sizeof(float));
+      memset(sofar[i],0,sizeof(float)*n/2);
+    }
 
+    pcmbundle=alloca(sizeof(float *)*vi->channels);
+    sobundle=alloca(sizeof(float *)*vi->channels);
+    zerobundle=alloca(sizeof(int)*vi->channels);
+
+    /* initial down-quantized coupling */
+    _vp_quantize_couple(look->psy_look,
+			info,
+			pcm,
+			sofar,
+			quantized,
+			nonzero,
+			0);
+  
+    /* classify, by submap */
 
-	if(ang>=fabs(mag*2))ang=-fabs(mag*2);
-	
-	pcmM[j]=mag;
-	pcmA[j]=ang;
+    for(i=0;i<info->submaps;i++){
+      int ch_in_bundle=0;
+      pcmbundle[i]=pcmbundle+chcounter;
+      sobundle[i]=sobundle+chcounter;
+      zerobundle[i]=zerobundle+chcounter;
+
+      for(j=0;j<vi->channels;j++){
+	if(info->chmuxlist[j]==i){
+	  if(nonzero[j])
+	    zerobundle[i][ch_in_bundle]=1;
+	  else
+	    zerobundle[i][ch_in_bundle]=0;
+	  pcmbundle[i][ch_in_bundle]=quantized[j];
+	  sobundle[i][ch_in_bundle++]=sofar[j];
+	}
       }
+      chbundle[i]=ch_in_bundle;
+      chcounter+=ch_in_bundle;
+
+      classifications[i]=look->residue_func[i]->
+	class(vb,look->residue_look[i],pcmbundle[i],zerobundle[i],chbundle[i]);
     }
-  }
-  
-  /* perform residue encoding with residue mapping; this is
-     multiplexed.  All the channels belonging to one submap are
-     encoded (values interleaved), then the next submap, etc */
-  
-  for(i=0;i<info->submaps;i++){
-    int ch_in_bundle=0;
-    for(j=0;j<vi->channels;j++){
-      if(info->chmuxlist[j]==i){
-	if(nonzero[j])
-	  zerobundle[ch_in_bundle]=1;
-	else
-	  zerobundle[ch_in_bundle]=0;
-	pcmbundle[ch_in_bundle++]=vb->pcm[j];
+
+    /* actual encoding loop */
+    for(i=0;!stopflag;){
+
+      /* perform residue encoding of this pass's quantized residue
+         vector, according residue mapping */
+    
+      for(j=0;j<info->submaps;j++)
+	look->residue_func[j]->
+	  forward(vb,look->residue_look[j],
+		  pcmbundle[j],sobundle[j],zerobundle[j],chbundle[j],
+		  i,classifications[j]);
+      i++;
+      
+      /* bitrate management decision hook; the following if() is where
+         we tell progressive encoding to halt, right now it just
+         avoids falling off the edge */
+      if(i>=quant_passes /* || yadda yadda */)stopflag=1;
+
+      if(!stopflag){
+	/* down-couple/down-quantize from perfect-'so-far' -> 
+	   new quantized vector */
+	_vp_quantize_couple(look->psy_look,
+			    info,
+			    pcm,
+			    sofar,
+			    quantized,
+			    nonzero,
+			    i);
       }
+      /* steady as she goes */
     }
-    
-    look->residue_func[i]->forward(vb,look->residue_look[i],
-				   pcmbundle,zerobundle,ch_in_bundle);
   }
   
   look->lastframe=vb->sequence;

1.48.2.3  +253 -98   vorbis/lib/psy.c

Index: psy.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/psy.c,v
retrieving revision 1.48.2.2
retrieving revision 1.48.2.3
diff -u -r1.48.2.2 -r1.48.2.3
--- psy.c	2001/07/11 00:41:51	1.48.2.2
+++ psy.c	2001/08/02 06:14:44	1.48.2.3
@@ -7,11 +7,11 @@
  *                                                                  *
  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
-
+ *                                                                  *
  ********************************************************************
 
  function: psychoacoustics not including preecho
- last mod: $Id: psy.c,v 1.48.2.2 2001/07/11 00:41:51 xiphmont Exp $
+ last mod: $Id: psy.c,v 1.48.2.3 2001/08/02 06:14:44 xiphmont Exp $
 
  ********************************************************************/
 
@@ -213,7 +213,7 @@
 
 void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
                   vorbis_info_psy_global *gi,int n,long rate){
-  long i,j,lo=0,hi=0;
+  long i,j,k,lo=0,hi=0;
   long maxoc;
   memset(p,0,sizeof(vorbis_look_psy));
 
@@ -312,6 +312,25 @@
   memcpy(p->tonecurves[16][8]+2,tone_8000_80dB_SL,sizeof(float)*EHMER_MAX);
   memcpy(p->tonecurves[16][10]+2,tone_8000_100dB_SL,sizeof(float)*EHMER_MAX);
 
+  /* value limit the tonal masking curves; the peakatt not only
+     optionally specifies maximum dynamic depth, but also [always]
+     limits the masking curves to a minimum depth */
+  for(i=0;i<P_BANDS;i+=2)
+    for(j=4;j<P_LEVELS;j+=2){
+      float neutraldB=-vi->toneatt[i][j];
+      for(k=2;k<EHMER_MAX+2;k++)
+	if(p->tonecurves[i][j][k]-neutraldB>vi->peakatt[i][j])
+	  p->tonecurves[i][j][k]=neutraldB+vi->peakatt[i][j];
+    }
+
+  if(vi->peakattp) /* we limit depth only optionally */
+    for(j=4;j<P_LEVELS;j+=2){
+      float neutraldB=-vi->toneatt[i][j];
+      if(p->tonecurves[i][j][EHMER_OFFSET]-neutraldB<vi->peakatt[i][j])
+	p->tonecurves[i][j][EHMER_OFFSET]=neutraldB+vi->peakatt[i][j];
+    }
+
+
   /* interpolate curves between */
   for(i=1;i<P_BANDS;i+=2)
     for(j=4;j<P_LEVELS;j+=2){
@@ -428,8 +447,7 @@
                       const float **att,
                       const float *f, 
                       const float *flr,
-		      float *minseed,
-		      float *maxseed,
+		      float *seed,
                       float specmax){
   vorbis_info_psy *vi=p->vi;
   long n=p->n,i;
@@ -450,15 +468,18 @@
         if(oc>=P_BANDS)oc=P_BANDS-1;
         if(oc<0)oc=0;
         if(vi->tonemaskp)
-	  seed_curve(minseed,
+	  seed_curve(seed,
                      curves[oc],
-		     max,
+		     max+vi->tone_masteratt,
                      p->octave[i]-p->firstoc,
                      p->total_octave_lines,
                      p->eighth_octave_lines,
                      dBoffset);
-	if(vi->peakattp)
-	  seed_peak(maxseed,
+
+	if(vi->peakattp && !vi->tonemaskp) /* if tonemaskp is set,
+					      it's built into the
+					      masking curve */
+	  seed_peak(seed,
                     att[oc],
                     max,
                     p->octave[i]-p->firstoc,
@@ -541,85 +562,39 @@
 
 }
 
-static int seq=0;
-static void _vp_compute_mask_decay(vorbis_look_psy *p,
-				   vorbis_look_psy_global *g,
-				   float *seed,int channel){
-  if(g->gi->decaydBpms<0){
-    int i;
-
-    /* first decay the entire cached buffer */
-    float *decay=g->decay[channel];
-    float ms=p->n*1000.f/p->rate;
-    float decaydB=g->gi->decaydBpms*ms;
-
-    for(i=0;i<g->decaylines;i++){
-      decay[i]+=decaydB;
-      if(decay[i]<-9999.f)decay[i]=-9999.f;
-    }
-    _analysis_output("decay",seq,decay+200,g->decaylines-200,0,0);
-    _analysis_output("seed",seq++,seed-p->firstoc+200,p->total_octave_lines+p->firstoc-200,0,0);
-
-    /* now, apply decayed buffer to the valid range of the seeds,
-       copy back larger seeds into cache */
-    {
-      float end=p->total_octave_lines+p->firstoc-1;
-      int begin=-p->firstoc;
-
-      if(end>g->decaylines)end=g->decaylines;
-      if(begin<260)begin=260;
-      for(i=begin;i<end;i++){
-	if(decay[i]>seed[i-p->firstoc])
-	  seed[i-p->firstoc]=decay[i];
-	else
-	  decay[i]=seed[i-p->firstoc];
-      }
-    }
-  }
-}
-
-
 /* bleaugh, this is more complicated than it needs to be */
 static void max_seeds(vorbis_look_psy *p,
                       vorbis_look_psy_global *g,
                       int channel,
-		      float *minseed,float *maxseed,
+		      float *seed,
                       float *flr){
   long   n=p->total_octave_lines;
   int    linesper=p->eighth_octave_lines;
   long   linpos=0;
   long   pos;
 
-  seed_chase(minseed,linesper,n); /* for masking */
-  _vp_compute_mask_decay(p,g,minseed,channel);
-
-  seed_chase(maxseed,linesper,n); /* for peak att */
+  seed_chase(seed,linesper,n); /* for masking */
  
   pos=p->octave[0]-p->firstoc-(linesper>>1);
   while(linpos+1<p->n){
-    float min=minseed[pos];
-    float max=maxseed[pos];
+    float min=seed[pos];
     long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc;
     while(pos+1<=end){
       pos++;
-      if((minseed[pos]>NEGINF && minseed[pos]<min) || min==NEGINF)
-	min=minseed[pos];
-      if(maxseed[pos]>max)max=maxseed[pos];
+      if((seed[pos]>NEGINF && seed[pos]<min) || min==NEGINF)
+	min=seed[pos];
     }
-    if(max<min)max=min;
     
     /* seed scale is log.  Floor is linear.  Map back to it */
     end=pos+p->firstoc;
     for(;linpos<p->n && p->octave[linpos]<=end;linpos++)
-      if(flr[linpos]<max)flr[linpos]=max;
+      if(flr[linpos]<min)flr[linpos]=min;
   }
   
   {
-    float min=minseed[p->total_octave_lines-1];
-    float max=maxseed[p->total_octave_lines-1];
-    if(max<min)max=min;
+    float min=seed[p->total_octave_lines-1];
     for(;linpos<p->n;linpos++)
-      if(flr[linpos]<max)flr[linpos]=max;
+      if(flr[linpos]<min)flr[linpos]=min;
   }
   
 }
@@ -706,10 +681,18 @@
     /* move the median if needed */
     {
       int bark_th = (thresh[i]*(hi-lo)+512)/1024;
-      
+
       if(fixed>0){
         int fixed_th = (thresh[i]*(fixedc)+512)/1024;
         
+	while(bark_th<barkcountbelow ||
+	      fixed_th<fixedcountbelow /* && median>=0 by rep invariant */
+	      ){
+	  barkcountbelow-=barkradix[median];
+	  fixedcountbelow-=fixedradix[median];
+	  median--;
+	}
+
         while(bark_th>=barkcountbelow && 
               fixed_th>=fixedcountbelow /* && median<LASTBIN by rep invariant */
               ){
@@ -718,23 +701,16 @@
           fixedcountbelow+=fixedradix[median];
         }
         
-	while(bark_th<barkcountbelow ||
-	      fixed_th<fixedcountbelow /* && median>=0 by rep invariant */
-	      ){
+      }else{
+	while(bark_th<barkcountbelow){
           barkcountbelow-=barkradix[median];
-	  fixedcountbelow-=fixedradix[median];
           median--;
         }
-      }else{
         while(bark_th>=barkcountbelow){
           median++;
           barkcountbelow+=barkradix[median];
         }
         
-	while(bark_th<barkcountbelow){
-	  barkcountbelow-=barkradix[median];
-	  median--;
-	}
       }
     }
 
@@ -742,28 +718,40 @@
   }
 
 }
+
+
+void _vp_remove_floor(vorbis_look_psy *p,
+		      vorbis_look_psy_global *g,
+		      float *logmdct, 
+		      float *mdct,
+		      float *codedflr,
+		      float *residue,
+		      float local_specmax){ 
+  int i,n=p->n;
+  
+  for(i=0;i<n;i++)
+    if(mdct[i]!=0.f)
+      residue[i]=mdct[i]/codedflr[i];
+    else
+      residue[i]=0.f;
+}
+  
 
-float _vp_compute_mask(vorbis_look_psy *p,
+void _vp_compute_mask(vorbis_look_psy *p,
                        vorbis_look_psy_global *g,
                        int channel,
                        float *fft, 
                        float *mdct, 
                        float *mask, 
-		       float specmax,
+		       float global_specmax,
+		       float local_specmax,
                        int lastsize){
   int i,n=p->n;
-  float localmax=NEGINF;
   static int seq=0;
 
-  float *minseed=alloca(sizeof(float)*p->total_octave_lines);
-  float *maxseed=alloca(sizeof(float)*p->total_octave_lines);
-  for(i=0;i<p->total_octave_lines;i++)minseed[i]=maxseed[i]=NEGINF;
+  float *seed=alloca(sizeof(float)*p->total_octave_lines);
+  for(i=0;i<p->total_octave_lines;i++)seed[i]=NEGINF;
 
-  /* 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;
-
   /* noise masking */
   if(p->vi->noisemaskp){
     bark_noise_median(n,p->bark,mdct,mask,
@@ -774,11 +762,11 @@
                       p->noisemedian,
                       p->noiseoffset,
                       p->vi->noisewindowfixed);
-    /* suppress any noise curve > specmax+p->vi->noisemaxsupp */
+    /* suppress any noise curve > global_specmax+p->vi->noisemaxsupp */
     for(i=0;i<n;i++)
-      if(mask[i]>specmax+p->vi->noisemaxsupp)
-	mask[i]=specmax+p->vi->noisemaxsupp;
-    _analysis_output("noise",seq,mask,n,0,0);
+      if(mask[i]>global_specmax+p->vi->noisemaxsupp)
+	mask[i]=global_specmax+p->vi->noisemaxsupp;
+    _analysis_output("noise",seq,mask,n,1,0);
   }else{
     for(i=0;i<n;i++)mask[i]=NEGINF;
   }
@@ -786,7 +774,7 @@
   /* set the ATH (floating below localmax, not global max by a
      specified att) */
   if(p->vi->ath){
-    float att=localmax+p->vi->ath_adjatt;
+    float att=local_specmax+p->vi->ath_adjatt;
     if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
 
     for(i=0;i<n;i++){
@@ -797,13 +785,9 @@
 
 
   /* tone/peak masking */
-
-  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,g,channel,minseed,maxseed,mask);
+  seed_loop(p,(const float ***)p->tonecurves,
+	    (const float **)p->peakatt,fft,mask,seed,global_specmax);
+  max_seeds(p,g,channel,seed,mask);
 
   /* doing this here is clean, but we need to find a faster way to do
      it than to just tack it on */
@@ -812,10 +796,12 @@
   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]);
+    for(i=0;i<n;i++){
+      mask[i]+=p->vi->floor_masteratt;
+      fft[i]=max(mdct[i],fft[i]);
+    }
   seq++;
 
-  return(specmax);
 }
 
 float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){
@@ -831,5 +817,174 @@
   return(amp);
 }
 
+static void couple_lossless(float A, float B, float *mag, float *ang,float t){
+  float fmag;
+  
+  if(fabs(A)>fabs(B)){
+    fmag=fabs(*mag=A); *ang=(A>0.f?A-B:B-A);
+  }else{
+    fmag=fabs(*mag=B); *ang=(B>0.f?A-B:B-A);
+  }
+
+  if(*ang>fmag*1.9999f)*ang=-fmag*2.f;
 
+}
+
+static void couple_8phase(float A, float B, float *mag, float *ang,float t){
+  float fmag;
 
+  if(fabs(A)>fabs(B)){
+    fmag=fabs(*mag=A); *ang=(A>0?A-B:B-A);
+  }else{
+    fmag=fabs(*mag=B); *ang=(B>0?A-B:B-A);
+  }
+
+  if(fmag>0.f)
+    switch((int)(rint(*ang/fmag))){
+    case 0:
+      if(fmag>t){
+	if(*ang>fmag-t)*ang=fmag-t;
+	if(*ang<t-fmag)*ang=t-fmag;
+      }else{
+	*ang=0;
+      }
+      break;
+    case 2:case -2:
+      *ang=-2*fmag;
+      break;
+    case 1:
+      *ang=fmag;
+      break;
+    case -1:
+      *ang=-fmag;
+      break;
+    }
+}
+
+static void couple_6phase(float A, float B, float *mag, float *ang,float t){
+  float fmag;
+  
+  if(fabs(A)>fabs(B)){
+    fmag=fabs(*mag=A); *ang=(A>0?A-B:B-A);
+  }else{
+    fmag=fabs(*mag=B); *ang=(B>0?A-B:B-A);
+  }
+
+  if(fmag>0.f)
+    switch((int)(rint(*ang/fmag))){
+    case -2:case 2:
+      *ang=0;
+      *mag=0;
+      break;
+    case 0:
+      if(fmag>t){
+	if(*ang>fmag-t)*ang=fmag-t;
+	if(*ang<t-fmag)*ang=t-fmag;
+      }else{
+	*ang=0;
+      }
+      break;
+    case 1:
+      *ang=fmag;
+      break;
+    case -1:
+      *ang=-fmag;
+      break;
+    }
+}
+
+static void couple_point(float A, float B, float *mag, float *ang,float t){
+  float fmag;
+  
+  if(fabs(A)>fabs(B)){
+    fmag=fabs(*mag=A); *ang=(A>0?A-B:B-A);
+  }else{
+    fmag=fabs(*mag=B); *ang=(B>0?A-B:B-A);
+  }
+
+  if(fmag>0.f)
+    switch((int)(rint(*ang/fmag))){
+    case 0:
+      if(fmag>t){
+	if(*ang>fmag-t)*ang=fmag-t;
+	if(*ang<t-fmag)*ang=t-fmag;
+      }else{
+	*ang=0;
+      }
+      break;
+
+    case 1:
+    case -1:
+      *ang=0;
+      break;
+
+    case -2:
+    case 2:
+      *mag=0;
+      *ang=0;
+      break;
+    }
+}
+
+void _vp_quantize_couple(vorbis_look_psy *p,
+			 vorbis_info_mapping0 *vi,
+			 float **pcm,
+			 float **sofar,
+			 float **quantized,
+			 int   *nonzero
+			 int   passno){
+
+  int i,j,k,l,n=p->n;
+  vorbis_info_psy *info=p->vi;
+  float granule=info->couple_pass[passno]->granule;
+  float igranule=info->couple_pass[passno]->igranule;
+
+  /* perform any requested channel coupling */
+  for(i=0;i<vi->coupling_steps;i++){
+    
+    /* make sure coupling a zero and a nonzero channel results in two
+       nonzero channels. */
+    if(nonzero[vi->coupling_mag[i]] ||
+       nonzero[vi->coupling_ang[i]]){
+      
+      float *pcmM=pcm[vi->coupling_mag[i]];
+      float *pcmA=pcm[vi->coupling_ang[i]];
+      float *sofarM=sofar[vi->coupling_mag[i]];
+      float *sofarA=sofar[vi->coupling_ang[i]];
+      float *qM=quantized[vi->coupling_mag[i]];
+      float *qA=quantized[vi->coupling_ang[i]];
+
+      nonzero[vi->coupling_mag[i]]=1; 
+      nonzero[vi->coupling_ang[i]]=1; 
+
+      for(j=0,k=0;j<n;k++){
+	vp_couple *part=info->couple_pass[passno]->couple+k;
+
+	for(;j<info->partition*part->partition_limit && j<p->n;j++){
+	  /* partition by partition; k is our by-location partition
+	     class counter */
+	  float ang,mag=max(fabs(pcmM[j]),fabs(pcmA[j]));
+	  float M=rint(pcmM[j]*igranule)*granule;
+	  float A=rint(pcmA[j]*igranule)*granule;
+	  
+	  if(mag<part->couple_point.amppost){
+	    couple_point(M,A,&mag,&ang,part->couple_point.threshhold);
+	  }else{
+	    if(mag<part->couple_sixphase.amppost){
+	      couple_6phase(M,A,&mag,&ang,part->couple_point.threshhold);
+	    }else{ 
+	      if(mag<part->couple_eightphase.amppost){
+		couple_8phase(M,A,&mag,&ang,part->couple_point.threshhold);
+	      }else{
+		couple_lossless(M,A,&mag,&ang,part->couple_point.threshhold);
+	      }
+	    }
+	  }
+	  
+	  qM[j]=mag-sofarM[j];
+	  qA[j]=ang-sofarA[j];
+	}
+      }
+    }
+  }
+}

1.15.2.1  +276 -125  vorbis/lib/psytune.c

Index: psytune.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/psytune.c,v
retrieving revision 1.15
retrieving revision 1.15.2.1
diff -u -r1.15 -r1.15.2.1
--- psytune.c	2001/05/27 06:44:00	1.15
+++ psytune.c	2001/08/02 06:14:44	1.15.2.1
@@ -12,7 +12,7 @@
 
  function: simple utility that runs audio through the psychoacoustics
            without encoding
- last mod: $Id: psytune.c,v 1.15 2001/05/27 06:44:00 xiphmont Exp $
+ last mod: $Id: psytune.c,v 1.15.2.1 2001/08/02 06:14:44 xiphmont Exp $
 
  ********************************************************************/
 
@@ -22,6 +22,7 @@
 #include <math.h>
 
 #include "vorbis/codec.h"
+#include "codec_internal.h"
 #include "os.h"
 #include "psy.h"
 #include "mdct.h"
@@ -30,70 +31,100 @@
 #include "scales.h"
 #include "lpc.h"
 #include "lsp.h"
+#include "masking.h"
+#include "registry.h"
 
-static vorbis_info_psy _psy_set0={
-  1,/*athp*/
-  1,/*decayp*/
+static vorbis_info_psy_global _psy_set0G={
+  0,   /* decaydBpms */
+  8,   /* lines per eighth octave */
+  
+  /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
+  256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
+  -6.f, 
+  
+  0,
+
+  0.,
+  0.,
+};
+
+static vp_part _vp_part0[]={
+  {    1,9e10f, 9e10f,       1.f,9999.f},
+  { 9999,  .75f, 9e10f,       .5f,9999.f},
+  //{ 9999, 1.5f, 9e10f,       .5f,9999.f},
+  {   18,9e10f, 9e10f,       .5f,  30.f},
+  { 9999,9e10f, 9e10f,       .5f,  30.f}
+};
 
+static vp_couple _vp_couple0[]={
+  {    1,  {9e10f,9e10f,0}, {   0.f,   0.f,0}, {   0.f, 0.f,0}, {0.f,0.f,0}},
+  {   18,  {9e10f,9e10f,0}, {   0.f,   0.f,0}, {   0.f, 0.f,0}, {0.f,0.f,0}},
+  { 9999,  {9e10f,9e10f,0}, {   0.f, 9e10f,0}, {   0.f,22.f,1}, {0.f,0.f,0}}
+};
+
+static vorbis_info_psy _psy_set0={
+  ATH_Bark_dB_lineaggressive,
+  
   -100.f,
   -140.f,
-
-  8,
+  6.f, /* floor master att */
 
   /*     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 */
+   1,  /* tonemaskp */
+  0.f, /* tone master att */
   /*  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*/
-
-   {-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*/
 
-   {-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*/
+   {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*175*/
+   {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*250*/
+   {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*350*/
+   {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*500*/
+   {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*700*/
+   {-30.f,-30.f,-35.f,-40.f,-40.f,-50.f,-60.f,-70.f,-80.f,-90.f,-100.f}, /*1000*/
+   {-30.f,-30.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*/
-   {-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*/
+   {-40.f,-40.f,-40.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*/
+
    {-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*/
+   {-30.f,-30.f,-33.f,-35.f,-40.f,-45.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*11500*/
+   {-24.f,-24.f,-26.f,-32.f,-32.f,-42.f,-50.f,-60.f,-70.f,-85.f,-100.f}, /*16000*/
 
   },
 
   1,/* peakattp */
-  {{-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-24.f,-24.f,-24.f},/*63*/
-   {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-24.f,-24.f,-24.f},/*88*/
-   {-14.f,-16.f,-18.f,-19.f,-20.f,-21.f,-22.f,-22.f,-24.f,-24.f,-24.f},/*125*/
-   {-10.f,-10.f,-10.f,-10.f,-16.f,-16.f,-18.f,-20.f,-24.f,-24.f,-24.f},/*175*/
-   {-10.f,-10.f,-10.f,-10.f,-16.f,-16.f,-18.f,-20.f,-24.f,-24.f,-24.f},/*250*/
-   {-10.f,-10.f,-10.f,-10.f,-16.f,-16.f,-18.f,-20.f,-22.f,-24.f,-24.f},/*350*/
-   {-10.f,-10.f,-10.f,-10.f,-16.f,-16.f,-18.f,-20.f,-22.f,-24.f,-24.f},/*500*/
-   {-10.f,-10.f,-10.f,-10.f,-14.f,-14.f,-16.f,-20.f,-22.f,-24.f,-24.f},/*700*/
-   {-10.f,-10.f,-10.f,-10.f,-14.f,-14.f,-16.f,-20.f,-22.f,-24.f,-24.f},/*1000*/
-   {-10.f,-10.f,-10.f,-10.f,-14.f,-14.f,-16.f,-20.f,-22.f,-24.f,-24.f},/*1400*/
-   {-10.f,-10.f,-10.f,-10.f,-14.f,-14.f,-16.f,-20.f,-22.f,-24.f,-24.f},/*2000*/
-   {-10.f,-10.f,-10.f,-12.f,-16.f,-16.f,-16.f,-20.f,-22.f,-24.f,-24.f},/*2400*/
-   {-10.f,-10.f,-10.f,-12.f,-16.f,-16.f,-16.f,-20.f,-22.f,-24.f,-24.f},/*4000*/
-   {-10.f,-10.f,-10.f,-12.f,-12.f,-14.f,-16.f,-18.f,-22.f,-24.f,-24.f},/*5600*/
-   {-10.f,-10.f,-10.f,-10.f,-10.f,-14.f,-16.f,-18.f,-22.f,-24.f,-24.f},/*8000*/
-   {-10.f,-10.f,-10.f,-10.f,-10.f,-14.f,-16.f,-18.f,-22.f,-24.f,-24.f},/*11500*/
-   {-10.f,-10.f,-10.f,-10.f,-10.f,-12.f,-16.f,-18.f,-22.f,-24.f,-24.f},/*16000*/
+  {{-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*63*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*88*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*125*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*175*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*250*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*350*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*500*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*700*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1000*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*1400*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2000*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*2800*/
+   {-14.f,-20.f,-20.f,-20.f,-26.f,-32.f,-40.f,-40.f,-40.f,-40.f,-40.f},/*4000*/
+   {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*5600*/
+   {-10.f,-12.f,-14.f,-16.f,-16.f,-20.f,-24.f,-30.f,-32.f,-40.f,-40.f},/*8000*/
+   {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*11500*/
+   {-10.f,-10.f,-10.f,-12.f,-14.f,-18.f,-22.f,-28.f,-32.f,-40.f,-40.f},/*16000*/
   },
 
   1,/*noisemaskp */
-  -24.f,  /* suppress any noise curve over maxspec+n */
+  -10.f,  /* suppress any noise curve over maxspec+n */
   .5f,   /* low window */
   .5f,   /* high window */
-  25,
+  10,
+  10,
   25,
   {.000f, 0.f, /*63*/
    .000f, 0.f, /*88*/
@@ -102,25 +133,65 @@
    .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*/
+   .000f, 0.f, /*700*/
+   .000f, 0.f, /*1000*/
+   .300f, 0.f, /*1400*/
+   .300f, 0.f, /*2000*/
+   .300f, 0.f, /*2800*/
+   .500f, 0.f, /*4000*/
+   .700f, 0.f, /*5600*/
+   .850f, 0.f, /*8000*/
    .900f, 0.f, /*11500*/
    .900f, 1.f, /*16000*/
   },
  
   95.f,  /* even decade + 5 is important; saves an rint() later in a
             tight loop) */
-  -28.,
+  -44.,
 
+  32,
+  _vp_part0,_vp_couple0
 };
 
-static int noisy=1;
+static vorbis_info_floor1 _floor_set0={1,
+					{0},
+					
+					{32},
+					{0},
+					{0},
+					{{-1}},
+
+					2,
+					{0,1024,
+
+					 88,31,243,
+
+					 14,54,143,460,
+					 
+					 6,3,10, 22,18,26, 41,36,47, 
+					 69,61,78, 112,99,126, 185,162,211,  
+					 329,282,387, 672,553,825
+					 },
+					
+					60,30,400,
+					20,8,1,18.,
+					20,600,
+					960};
+
+
+static vorbis_info_mapping0 mapping_info={1,{0,1},{0},{0},{0},0, 1, {0},{1}};
+static codec_setup_info codec_setup0={ {0,0}, 
+				       1,1,1,1,1,0,1,	
+				       {NULL},
+				       {0},{&mapping_info},
+				       {0},{NULL},
+				       {1},{&_floor_set0},
+				       {2},{NULL},
+				       {NULL},
+				       {&_psy_set0},
+				       &_psy_set0G};
+				       
+static int noisy=0;
 void analysis(char *base,int i,float *v,int n,int bark,int dB){
   if(noisy){
     int j;
@@ -139,7 +210,7 @@
           fprintf(of,"%g ",(float)j);
       
         if(dB){
-	  fprintf(of,"%g\n",todB(fabs(v+j)));
+	  fprintf(of,"%g\n",todB(v+j));
         }else{
           fprintf(of,"%g\n",v[j]);
         }
@@ -159,18 +230,19 @@
   float acc=0.f;
   float tot=0.f;
   float ampmax=-9999,newmax;
+  float local_ampmax[2];
 
   int framesize=2048;
-  int order=30;
-  int map=256;
-  float ampmax_att_per_sec=-10.;
+  float ampmax_att_per_sec=-6.;
 
-  float *pcm[2],*out[2],*window,*lpc,*flr,*mask;
+  float *pcm[2],*out[2],*window,*flr[2],*mask[2],*work[2];
   signed char *buffer,*buffer2;
   mdct_lookup m_look;
   drft_lookup f_look;
-  drft_lookup f_look2;
   vorbis_look_psy p_look;
+  vorbis_look_psy_global *pg_look;
+  vorbis_look_floor *floor_look;
+  vorbis_info vi;
   long i,j,k;
 
   int ath=0;
@@ -183,47 +255,36 @@
       if(argv[0][1]=='v'){
         noisy=0;
       }
-      if(argv[0][1]=='o'){
-	order=atoi(argv[0]+2);
-      }
-      if(argv[0][1]=='m'){
-	map=atoi(argv[0]+2);
-      }
     }else
       if(*argv[0]=='+'){
         /* option */
         if(argv[0][1]=='v'){
           noisy=1;
         }
-	if(argv[0][1]=='o'){
-	  order=atoi(argv[0]+2);
-	}
-	if(argv[0][1]=='m'){
-	  map=atoi(argv[0]+2);
-	}
       }else
         framesize=atoi(argv[0]);
     argv++;
   }
   
-  mask=_ogg_malloc(framesize*sizeof(float));
+  vi.channels=2;
+  vi.codec_setup=&codec_setup0;
+
   pcm[0]=_ogg_malloc(framesize*sizeof(float));
   pcm[1]=_ogg_malloc(framesize*sizeof(float));
   out[0]=_ogg_calloc(framesize/2,sizeof(float));
   out[1]=_ogg_calloc(framesize/2,sizeof(float));
-  flr=_ogg_malloc(framesize*sizeof(float));
-  lpc=_ogg_malloc(order*sizeof(float));
+  work[0]=_ogg_calloc(framesize,sizeof(float));
+  work[1]=_ogg_calloc(framesize,sizeof(float));
+  flr[0]=_ogg_calloc(framesize/2,sizeof(float));
+  flr[1]=_ogg_calloc(framesize/2,sizeof(float));
   buffer=_ogg_malloc(framesize*4);
   buffer2=buffer+framesize*2;
   window=_vorbis_window(0,framesize,framesize/2,framesize/2);
   mdct_init(&m_look,framesize);
   drft_init(&f_look,framesize);
-  drft_init(&f_look2,framesize/2);
-  _vp_psy_init(&p_look,&_psy_set0,framesize/2,44100);
-
-  for(i=0;i<P_BANDS;i++)
-    for(j=0;j<P_LEVELS;j++)
-      analysis("Ptonecurve",i*100+j,p_look.tonecurves[i][j],EHMER_MAX,0,0);
+  _vp_psy_init(&p_look,&_psy_set0,&_psy_set0G,framesize/2,44100);
+  pg_look=_vp_global_look(&vi);
+  floor_look=_floor_P[1]->look(NULL,NULL,&_floor_set0);
 
   /* we cheat on the WAV header; we just bypass 44 bytes and never
      verify that it matches 16bit/stereo/44.1kHz. */
@@ -242,6 +303,7 @@
       memset(buffer2+bytes,0,framesize*2-bytes);
     
     if(bytes!=0){
+      int nonzero[2];
 
       /* uninterleave samples */
       for(i=0;i<framesize;i++){
@@ -257,93 +319,181 @@
         ampmax+=secs*ampmax_att_per_sec;
         if(ampmax<-9999)ampmax=-9999;
       }
-      newmax=ampmax;
 
       for(i=0;i<2;i++){
-	float amp;
+	float scale=4.f/framesize;
+	float *fft=work[i];
+	float *mdct=pcm[i];
+	float *logmdct=mdct+framesize/2;
 
-	analysis("pre",frameno,pcm[i],framesize,0,0);
-	memcpy(mask,pcm[i],sizeof(float)*framesize);
+	analysis("pre",frameno+i,pcm[i],framesize,0,0);
         
-	/* do the psychacoustics */
+	/* fft and mdct transforms  */
         for(j=0;j<framesize;j++)
-	  mask[j]=pcm[i][j]*=window[j];
+	  fft[j]=pcm[i][j]*=window[j];
         
-	drft_forward(&f_look,mask);
+	drft_forward(&f_look,fft);
 
-	mask[0]/=(framesize/4.);
-	for(j=1;j<framesize-1;j+=2)
-	  mask[(j+1)>>1]=4*hypot(mask[j],mask[j+1])/framesize;
-
-	mdct_forward(&m_look,pcm[i],pcm[i]);
-	memcpy(mask+framesize/2,pcm[i],sizeof(float)*framesize/2);
-	analysis("mdct",frameno,pcm[i],framesize/2,0,1);
-	analysis("fft",frameno,mask,framesize/2,0,1);
-
-	{
-	  float ret;
-	  ret=_vp_compute_mask(&p_look,mask,mask+framesize/2,flr,NULL,ampmax);
-	  if(ret>newmax)newmax=ret;
+	local_ampmax[i]=-9999.f;
+	fft[0]*=scale;
+	fft[0]=todB(fft);
+	for(j=1;j<framesize-1;j+=2){
+	  float temp=scale*FAST_HYPOT(fft[j],fft[j+1]);
+	  temp=fft[(j+1)>>1]=todB(&temp);
+	  if(temp>local_ampmax[i])local_ampmax[i]=temp;
         }
+	if(local_ampmax[i]>ampmax)ampmax=local_ampmax[i];
+	
+	mdct_forward(&m_look,pcm[i],mdct);
+	for(j=0;j<framesize/2;j++)
+	  logmdct[j]=todB(mdct+j);
 
-	analysis("mask",frameno,flr,framesize/2,0,0);
+	analysis("mdct",frameno+i,logmdct,framesize/2,1,0);
+	analysis("fft",frameno+i,fft,framesize/2,1,0);
+      }
 
-	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;
+      for(i=0;i<2;i++){
+	float amp;
+	float *fft=work[i];
+	float *logmax=fft;
+	float *mdct=pcm[i];
+	float *logmdct=mdct+framesize/2;
+	float *mask=fft+framesize/2;
+
+	/* floor psychoacoustics */
+	_vp_compute_mask(&p_look,
+			 pg_look,
+			 i,
+			 fft,
+			 logmdct,
+			 mask,
+			 ampmax,
+			 local_ampmax[i],
+			 framesize/2);
+
+	analysis("mask",frameno+i,mask,framesize/2,1,0);
+
+	{
+	  vorbis_block vb;
+	  vorbis_dsp_state vd;
+	  memset(&vd,0,sizeof(vd));
+	  vd.vi=&vi;
+	  vb.vd=&vd;
+	  vb.pcmend=framesize;
+
+	  /* floor quantization/application */
+	  nonzero[i]=_floor_P[1]->forward(&vb,floor_look,
+					  mdct,
+					  logmdct,
+					  mask,
+					  logmax,
+					  
+					  flr[i]);
         }
 
-	analysis("lfft",frameno,mask,framesize,0,0);
-	drft_backward(&f_look,mask);
+	_vp_remove_floor(&p_look,
+			 pg_look,
+			 logmdct,
+			 mdct,
+			 flr[i],
+			 pcm[i],
+			 local_ampmax[i]);
+
+	for(j=0;j<framesize/2;j++)
+	  if(fabs(pcm[i][j])>1500)
+	    fprintf(stderr,"%ld ",frameno+i);
+	
+	analysis("res",frameno+i,pcm[i],framesize/2,1,0);
+	analysis("codedflr",frameno+i,flr[i],framesize/2,1,1);
+      }
 
-	analysis("cep",frameno,mask,framesize,0,0);
-	analysis("logcep",frameno,mask,framesize,0,1);
+      /* residue prequantization */
+      _vp_partition_prequant(&p_look,
+			     &vi,
+			     pcm,
+			     nonzero);
         
+      for(i=0;i<2;i++)
+	analysis("quant",frameno+i,pcm[i],framesize/2,1,0);
 
+      /* channel coupling / stereo quantization */
 
-	/*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.;
-	    }*/
+      _vp_couple(&p_look,
+		 &mapping_info,
+		 pcm,
+		 nonzero);
+  
+      for(i=0;i<2;i++)
+	analysis("coupled",frameno+i,pcm[i],framesize/2,1,0);
 
+      /* decoupling */
+      for(i=mapping_info.coupling_steps-1;i>=0;i--){
+	float *pcmM=pcm[mapping_info.coupling_mag[i]];
+	float *pcmA=pcm[mapping_info.coupling_ang[i]];
+	
         for(j=0;j<framesize/2;j++){
-	  float val=rint(todB(pcm[i]+j)/6);
-	  if(pcm[i][j]>0)
-	    pcm[i][j]=fromdB(val*6);
+	  float mag=pcmM[j];
+	  float ang=pcmA[j];
+	  
+	  if(mag>0)
+	    if(ang>0){
+	      pcmM[j]=mag;
+	      pcmA[j]=mag-ang;
+	    }else{
+	      pcmA[j]=mag;
+	      pcmM[j]=mag+ang;
+	    }
           else
-	    pcm[i][j]=-fromdB(val*6);
+	    if(ang>0){
+	      pcmM[j]=mag;
+	      pcmA[j]=mag+ang;
+	    }else{
+	      pcmA[j]=mag;
+	      pcmM[j]=mag-ang;
+	    }
         }
+      }
+    
+      for(i=0;i<2;i++)
+	analysis("decoupled",frameno+i,pcm[i],framesize/2,1,0);
+
+      for(i=0;i<2;i++){
+	float amp;
 
+	for(j=0;j<framesize/2;j++)
+	  pcm[i][j]*=flr[i][j];
 
-	analysis("final",frameno,pcm[i],framesize/2,0,1);
+	analysis("final",frameno+i,pcm[i],framesize/2,1,1);
 
         /* take it back to time */
         mdct_backward(&m_look,pcm[i],pcm[i]);
+
         for(j=0;j<framesize/2;j++)
           out[i][j]+=pcm[i][j]*window[j];
+
+	analysis("out",frameno+i,out[i],framesize/2,0,0);
+
 
-	frameno++;
       }
-      ampmax=newmax;
            
       /* write data.  Use the part of buffer we're about to shift out */
       for(i=0;i<2;i++){
         char  *ptr=buffer+i*2;
         float *mono=out[i];
+	int flag=0;
         for(j=0;j<framesize/2;j++){
           int val=mono[j]*32767.;
           /* might as well guard against clipping */
-	  if(val>32767)val=32767;
-	  if(val<-32768)val=-32768;
+	  if(val>32767){
+	    if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i);
+	    flag=1;
+	    val=32767;
+	  }
+	  if(val<-32768){
+	    if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i);
+	    flag=1;
+	    val=-32768;
+	  }
           ptr[0]=val&0xff;
           ptr[1]=(val>>8)&0xff;
           ptr+=4;
@@ -358,6 +508,7 @@
         for(j=0,k=framesize/2;j<framesize/2;j++,k++)
           out[i][j]=pcm[i][k]*window[k];
       }
+      frameno+=2;
     }else
       eos=1;
   }

1.8.2.1   +2 -1      vorbis/lib/registry.c

Index: registry.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/registry.c,v
retrieving revision 1.8
retrieving revision 1.8.2.1
diff -u -r1.8 -r1.8.2.1
--- registry.c	2001/06/15 21:15:40	1.8
+++ registry.c	2001/08/02 06:14:44	1.8.2.1
@@ -11,11 +11,12 @@
  ********************************************************************
 
  function: registry for time, floor, res backends and channel mappings
- last mod: $Id: registry.c,v 1.8 2001/06/15 21:15:40 xiphmont Exp $
+ last mod: $Id: registry.c,v 1.8.2.1 2001/08/02 06:14:44 xiphmont Exp $
 
  ********************************************************************/
 
 #include "vorbis/codec.h"
+#include "codec_internal.h"
 #include "registry.h"
 #include "misc.h"
 

1.32.2.2  +220 -67   vorbis/lib/res0.c

Index: res0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/res0.c,v
retrieving revision 1.32.2.1
retrieving revision 1.32.2.2
diff -u -r1.32.2.1 -r1.32.2.2
--- res0.c	2001/07/08 08:48:02	1.32.2.1
+++ res0.c	2001/08/02 06:14:44	1.32.2.2
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: residue backend 0, 1 and 2 implementation
- last mod: $Id: res0.c,v 1.32.2.1 2001/07/08 08:48:02 xiphmont Exp $
+ last mod: $Id: res0.c,v 1.32.2.2 2001/08/02 06:14:44 xiphmont Exp $
 
  ********************************************************************/
 
@@ -366,13 +366,11 @@
   return(bits);
 }
 
-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,
-				    codebook *,vorbis_look_residue0 *)){
-  long i,j,k,l,s;
+static long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
+		       float **in,int ch,
+		       int (*classify)(float *,int,vorbis_look_residue0 *,
+				       int,int)){
+  long i,j,s;
   vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   vorbis_info_residue0 *info=look->info;
 
@@ -385,26 +383,8 @@
   int partvals=n/samples_per_partition;
   int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
   long **partword=_vorbis_block_alloc(vb,ch*sizeof(long *));
-
-#ifdef TRAIN_RES
-  FILE *of;
-  char buffer[80];
-  int m;
-  
-  for(i=0;i<ch;i++){
-    sprintf(buffer,"residue_%d.vqd",vb->mode);
-    of=fopen(buffer,"a");
-    for(m=0;m<info->end;m++)
-      fprintf(of,"%.2f, ",in[i][m]);
-    fprintf(of,"\n");
-    fclose(of);
-  }
- 
-#endif      
 
-  partvals=partwords*partitions_per_word;
-
-  /* we find the patition type for each partition of each
+  /* we find the partition type for each partition of each
      channel.  We'll go back and do the interleaved encoding in a
      bit.  For now, clarity */
  
@@ -413,12 +393,13 @@
     memset(partword[i],0,n/samples_per_partition*sizeof(long));
   }
 
-  for(i=info->begin,l=0;i<info->end;i+=samples_per_partition,l++){
+  for(i=0;i<partvals;i++){
     for(j=0;j<ch;j++)
       /* do the partition decision based on the 'entropy'
          int the block */
-      partword[j][l]=
-	classify(in[j]+i,samples_per_partition,look,possible_partitions,l);
+      partword[j][i]=
+	classify(in[j]+i*samples_per_partition+info->begin,
+		 samples_per_partition,look,possible_partitions,i);
   
   }
 
@@ -430,55 +411,147 @@
     for(i=0;i<ch;i++){
       sprintf(buffer,"resaux_%d.vqd",vb->mode);
       of=fopen(buffer,"a");
-      for(j=info->begin,l=0;j<info->end;j+=samples_per_partition,l++)
-	fprintf(of,"%d, ",partword[i][l]);
+      for(j=0;j<partvals;j++)
+	fprintf(of,"%d, ",partword[i][j]);
       fprintf(of,"\n");
       fclose(of);
     }
   }
 #endif
-      
+  look->frames++;
+
+  return(partword);
+}
+
+static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,
+		       float **in,int ch,
+		       int (*classify)(float *,int,vorbis_look_residue0 *,
+				       int,int)){
+  long i,j,k,l,s;
+  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
+  vorbis_info_residue0 *info=look->info;
+
+  /* move all this setup out later */
+  int samples_per_partition=info->grouping;
+  int possible_partitions=info->partitions;
+  int partitions_per_word=look->phrasebook->dim;
+  int n=info->end-info->begin;
+
+  int partvals=n/samples_per_partition;
+  int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
+  long **partword=_vorbis_block_alloc(vb,sizeof(long *));
+  float *work=alloca(sizeof(float)*samples_per_partition);
+  
+  partword[0]=_vorbis_block_alloc(vb,n*ch/samples_per_partition*sizeof(long));
+  memset(partword[0],0,n*ch/samples_per_partition*sizeof(long));
+
+  for(i=0,j=0,k=0,l=info->begin;i<partvals;i++){
+    for(k=0;k<samples_per_partition;k++){
+      work[k]=vb->pcm[j][l];
+      j++;
+      if(j>=ch){
+	j=0;
+	l++;
+      }
+    }
+    partword[0][i]=
+      classify(work,samples_per_partition,look,possible_partitions,i);
+  }  
+
+#ifdef TRAIN_RES
+  {
+    FILE *of;
+    char buffer[80];
+  
+    sprintf(buffer,"resaux_%d.vqd",vb->mode);
+    of=fopen(buffer,"a");
+    for(i=0;i<partvals;i++)
+      fprintf(of,"%d, ",partword[0][i]);
+    fprintf(of,"\n");
+    fclose(of);
+  }
+#endif
+  look->frames++;
+
+  return(partword);
+}
+
+static int _01forward(vorbis_block *vb,vorbis_look_residue *vl,
+		      float **in,int ch,
+		      int pass,long **partword,
+		      int (*encode)(oggpack_buffer *,float *,int,
+				    codebook *,vorbis_look_residue0 *)){
+  long i,j,k,s;
+  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
+  vorbis_info_residue0 *info=look->info;
+
+  /* move all this setup out later */
+  int samples_per_partition=info->grouping;
+  int possible_partitions=info->partitions;
+  int partitions_per_word=look->phrasebook->dim;
+  int n=info->end-info->begin;
+
+  int partvals=n/samples_per_partition;
+  int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
+
+#ifdef TRAIN_RES
+  FILE *of;
+  char buffer[80];
+  int m;
+  
+  for(i=0;i<ch;i++){
+    sprintf(buffer,"residue_%d#%d.vqd",vb->mode,pass);
+    of=fopen(buffer,"a");
+    for(m=0;m<info->end;m++)
+      fprintf(of,"%.2f, ",in[i][m]);
+    fprintf(of,"\n");
+    fclose(of);
+  }
+#endif      
+  
   /* 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
      partition channel words... */
 
-  look->frames++;
-  for(s=0;s<look->stages;s++){
-    for(i=info->begin,l=0;i<info->end;){
+  for(s=(pass==0?0:info->passlimit[pass-1]);s<info->passlimit[pass];s++){
+    for(i=0;i<partvals;){
       
       /* first we encode a partition codeword for each channel */
       if(s==0){
         for(j=0;j<ch;j++){
-	  long val=partword[j][l];
+	  long val=partword[j][i];
           long ret;
-	  for(k=1;k<partitions_per_word;k++)
-	    val= val*possible_partitions+partword[j][l+k];
+	  for(k=1;k<partitions_per_word;k++){
+	    val*=possible_partitions;
+	    if(i+k<partvals)
+	      val+=partword[j][i+k];
+	  
           ret=vorbis_book_encode(look->phrasebook,val,&vb->opb);
           look->phrasebits+=ret;
         }
       }
       
       /* now we encode interleaved residual values for the partitions */
-      for(k=0;k<partitions_per_word;k++,l++,i+=samples_per_partition){
+      for(k=0;k<partitions_per_word && i<partvals;k++,i++){
         
         for(j=0;j<ch;j++){
-	  /*if(s==0)look->resvals[partword[j][l]]++;*/
-	  if(info->secondstages[partword[j][l]]&(1<<s)){
-	    codebook *statebook=look->partbooks[partword[j][l]][s];
+	  long offset=i*partvals+info->begin;
+	  /*if(s==0)look->resvals[partword[j][i]]++;*/
+	  if(info->secondstages[partword[j][i]]&(1<<s)){
+	    codebook *statebook=look->partbooks[partword[j][i]][s];
             if(statebook){
-	      int ret=encode(&vb->opb,in[j]+i,samples_per_partition,
+	      int ret=encode(&vb->opb,in[j]+offset,samples_per_partition,
                              statebook,look);
-	      /*look->resbits[partword[j][l]][s]+=ret;*/
+	      /*look->resbits[partword[j][i]][s]+=ret;*/
               look->postbits+=ret;
-
+	      
             }
           }
         }
       }
     }
   }
-  
   return(0);
 }
 
@@ -496,18 +569,19 @@
   int samples_per_partition=info->grouping;
   int partitions_per_word=look->phrasebook->dim;
   int n=info->end-info->begin;
-
+  
   int partvals=n/samples_per_partition;
   int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
   int ***partword=alloca(ch*sizeof(int **));
-  partvals=partwords*partitions_per_word;
 
   for(j=0;j<ch;j++)
     partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(int *));
 
   for(s=0;s<look->stages;s++){
-    for(i=info->begin,l=0;i<info->end;l++){
 
+    /* each loop decodes on partition codeword containing 
+       partitions_pre_word partitions */
+    for(i=0,l=0;i<partvals;l++){
       if(s==0){
         /* fetch the partition word for each channel */
         for(j=0;j<ch;j++){
@@ -519,12 +593,13 @@
       }
       
       /* now we decode residual values for the partitions */
-      for(k=0;k<partitions_per_word;k++,i+=samples_per_partition)
+      for(k=0;k<partitions_per_word && i<partvals;k++,i++)
         for(j=0;j<ch;j++){
+	  long offset=info->begin+i*samples_per_partition;
           if(info->secondstages[partword[j][l][k]]&(1<<s)){
             codebook *stagebook=look->partbooks[partword[j][l][k]][s];
             if(stagebook){
-	      if(decodepart(stagebook,in[j]+i,&vb->opb,
+	      if(decodepart(stagebook,in[j]+offset,&vb->opb,
                             samples_per_partition)==-1)goto eopbreak;
             }
           }
@@ -539,19 +614,45 @@
 
 /* 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 *nonzero,int ch){
+long **res0_class(vorbis_block *vb,vorbis_look_residue *vl,
+		  float **in,int *nonzero,int ch){
   /* we encode only the nonzero parts of a bundle */
   int i,used=0;
   for(i=0;i<ch;i++)
     if(nonzero[i])
       in[used++]=in[i];
   if(used)
-    return(_01forward(vb,vl,in,used,_interleaved_testhack,_interleaved_encodepart));
+    return(_01class(vb,vl,in,used,_interleaved_testhack));
   else
     return(0);
 }
 
+int res0_forward(vorbis_block *vb,vorbis_look_residue *vl,
+		 float **in,float **out,int *nonzero,int ch,
+		 int pass, long **partword){
+  /* we encode only the nonzero parts of a bundle */
+  int i,used=0,n=vb->pcmend/2;
+  for(i=0;i<ch;i++)
+    if(nonzero[i]){
+      for(j=0;j<n;j++)
+	out[i][j]+=in[i][j];
+      in[used++]=in[i];
+    }
+  if(used){
+    int ret=_01forward(vb,vl,in,used,pass,partword,
+		      _interleaved_encodepart);
+    used=0;
+    for(i=0;i<ch;i++)
+      if(nonzero[i]){
+	for(j=0;j<n;j++)
+	  out[i][j]-=in[used][j];
+	used++;
+      }
+    return(ret);
+  }else
+    return(0);
+}
+
 int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
                  float **in,int *nonzero,int ch){
   int i,used=0;
@@ -565,13 +666,38 @@
 }
 
 int res1_forward(vorbis_block *vb,vorbis_look_residue *vl,
-		 float **in,int *nonzero,int ch){
+		 float **in,float **out,int *nonzero,int ch,
+		 int pass, long **partword){
+  int i,used=0,n=vb->pcmend/2;
+  for(i=0;i<ch;i++)
+    if(nonzero[i]){
+      for(j=0;j<n;j++)
+	out[i][j]+=in[i][j];
+      in[used++]=in[i];
+    }
+
+  if(used){
+    int ret=_01forward(vb,vl,work,used,pass,partword,_encodepart);
+    used=0;
+    for(i=0;i<ch;i++)
+      if(nonzero[i]){
+	for(j=0;j<n;j++)
+	  out[i][j]-=in[used][j];
+	used++;
+      }
+    return(ret);
+  }else
+    return(0);
+}
+
+long **res1_class(vorbis_block *vb,vorbis_look_residue *vl,
+		  float **in,int *nonzero,int ch{
   int i,used=0;
   for(i=0;i<ch;i++)
     if(nonzero[i])
       in[used++]=in[i];
   if(used)
-    return(_01forward(vb,vl,in,used,_testhack,_encodepart));
+    return(_01class(vb,vl,in,used,_testhack));
   else
     return(0);
 }
@@ -588,25 +714,49 @@
     return(0);
 }
 
+long **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
+		  float **in,int *nonzero,int ch{
+  int i,used=0;
+  for(i=0;i<ch;i++)
+    if(nonzero[i])
+      in[used++]=in[i];
+  if(used)
+    return(_2class(vb,vl,in,used,_testhack));
+  else
+    return(0);
+}
+
 /* res2 is slightly more different; all the channels are interleaved
    into a single vector and encoded. */
+
 int res2_forward(vorbis_block *vb,vorbis_look_residue *vl,
-	    float **in,int *nonzero,int ch){
+		 float **in,float **out,int *nonzero,int ch,
+		 int pass,long **partword){
   long i,j,k,n=vb->pcmend/2,used=0;
 
   /* don't duplicate the code; use a working vector hack for now and
      reshape ourselves into a single channel res1 */
+  /* ugly; reallocs for each coupling pass :-( */
   float *work=_vorbis_block_alloc(vb,ch*n*sizeof(float));
   for(i=0;i<ch;i++){
-    float *pcm=vb->pcm[i];
+    float *pcm=in[i];
     if(nonzero[i])used++;
     for(j=0,k=i;j<n;j++,k+=ch)
       work[k]=pcm[j];
   }
   
-  if(used)
-    return(_01forward(vb,vl,&work,1,_testhack,_encodepart));
-  else
+  if(used){
+    int ret=_01forward(vb,vl,&work,1,pass,partword,_encodepart);
+    /* update the sofar vector */
+    for(i=0;i<ch;i++){
+      float *pcm=in[i];
+      float *sofar=out[i];
+      for(j=0,k=i;j<n;j++,k+=ch)
+	sofar[j]+=pcm[j]-work[k];
+    }
+
+    return(ret);
+  }else
     return(0);
 }
 
@@ -625,13 +775,12 @@
   int partvals=n/samples_per_partition;
   int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
   int **partword=_vorbis_block_alloc(vb,partwords*sizeof(int *));
-  partvals=partwords*partitions_per_word;
 
   for(i=0;i<ch;i++)if(nonzero[i])break;
   if(i==ch)return(0); /* no nonzero vectors */
 
   for(s=0;s<look->stages;s++){
-    for(i=info->begin,l=0;i<info->end;l++){
+    for(i=0,l=0;i<partvals;l++){
 
       if(s==0){
         /* fetch the partition word */
@@ -642,12 +791,13 @@
       }
 
       /* now we decode residual values for the partitions */
-      for(k=0;k<partitions_per_word;k++,i+=samples_per_partition)
+      for(k=0;k<partitions_per_word && i<partvals;k++,i++)
         if(info->secondstages[partword[l][k]]&(1<<s)){
           codebook *stagebook=look->partbooks[partword[l][k]][s];
-
+	  
           if(stagebook){
-	    if(vorbis_book_decodevv_add(stagebook,in,i,ch,
+	    if(vorbis_book_decodevv_add(stagebook,in,
+					i*samples_per_partition+info->begin,ch,
                                         &vb->opb,samples_per_partition)==-1)
               goto eopbreak;
           }
@@ -668,6 +818,7 @@
   &res0_copy_info,
   &res0_free_info,
   &res0_free_look,
+  &res0_class,
   &res0_forward,
   &res0_inverse
 };
@@ -679,6 +830,7 @@
   &res0_copy_info,
   &res0_free_info,
   &res0_free_look,
+  &res1_class,
   &res1_forward,
   &res1_inverse
 };
@@ -690,6 +842,7 @@
   &res0_copy_info,
   &res0_free_info,
   &res0_free_look,
+  &res2_class,
   &res2_forward,
   &res2_inverse
 };

1.22.2.2  +2 -1      vorbis/lib/synthesis.c

Index: synthesis.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/synthesis.c,v
retrieving revision 1.22.2.1
retrieving revision 1.22.2.2
diff -u -r1.22.2.1 -r1.22.2.2
--- synthesis.c	2001/07/08 08:48:02	1.22.2.1
+++ synthesis.c	2001/08/02 06:14:44	1.22.2.2
@@ -11,13 +11,14 @@
  ********************************************************************
 
  function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.22.2.1 2001/07/08 08:48:02 xiphmont Exp $
+ last mod: $Id: synthesis.c,v 1.22.2.2 2001/08/02 06:14:44 xiphmont Exp $
 
  ********************************************************************/
 
 #include <stdio.h>
 #include <ogg/ogg.h>
 #include "vorbis/codec.h"
+#include "codec_internal.h"
 #include "registry.h"
 #include "misc.h"
 #include "os.h"

1.9.6.1   +2 -1      vorbis/lib/time0.c

Index: time0.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/time0.c,v
retrieving revision 1.9
retrieving revision 1.9.6.1
diff -u -r1.9 -r1.9.6.1
--- time0.c	2001/02/26 03:50:43	1.9
+++ time0.c	2001/08/02 06:14:44	1.9.6.1
@@ -11,13 +11,14 @@
  ********************************************************************
 
  function: time backend 0 (dummy)
- last mod: $Id: time0.c,v 1.9 2001/02/26 03:50:43 xiphmont Exp $
+ last mod: $Id: time0.c,v 1.9.6.1 2001/08/02 06:14:44 xiphmont Exp $
 
  ********************************************************************/
 
 #include <stdlib.h>
 #include <string.h>
 #include "vorbis/codec.h"
+#include "codec_internal.h"
 #include "registry.h"
 #include "misc.h"
 

1.9.2.2   +8 -6      vorbis/lib/backends.h

Index: backends.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/backends.h,v
retrieving revision 1.9.2.1
retrieving revision 1.9.2.2
diff -u -r1.9.2.1 -r1.9.2.2
--- backends.h	2001/07/08 08:48:01	1.9.2.1
+++ backends.h	2001/08/02 06:14:44	1.9.2.2
@@ -12,7 +12,7 @@
 
  function: libvorbis backend and mapping structures; needed for 
            static mode headers
- last mod: $Id: backends.h,v 1.9.2.1 2001/07/08 08:48:01 xiphmont Exp $
+ last mod: $Id: backends.h,v 1.9.2.2 2001/08/02 06:14:44 xiphmont Exp $
 
  ********************************************************************/
 
@@ -61,9 +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 *, /* in */
                      const float *, const float *, /* in */
-		     const float *, const float *, /* in */
-		     float *, float *);            /* out */
+		     float *);                     /* out */
   void *(*inverse1)  (struct vorbis_block *,vorbis_look_floor *);
   int   (*inverse2)  (struct vorbis_block *,vorbis_look_floor *,
                      void *buffer,float *);
@@ -127,8 +127,10 @@
   vorbis_info_residue *(*copy_info)(vorbis_info_residue *);
   void (*free_info)    (vorbis_info_residue *);
   void (*free_look)    (vorbis_look_residue *);
-  int  (*forward)      (struct vorbis_block *,vorbis_look_residue *,
+  long (**class)       (struct vorbis_block *,vorbis_look_residue *,
                         float **,int *,int);
+  int  (*forward)      (struct vorbis_block *,vorbis_look_residue *,
+			float **,float **,int *,int,int,long **);
   int  (*inverse)      (struct vorbis_block *,vorbis_look_residue *,
                         float **,int *,int);
 } vorbis_func_residue;
@@ -150,7 +152,7 @@
   float  ampmax[64];       /* book amp threshholds*/
   int    subgrp[64];       /* book heuristic subgroup size */
   int    blimit[64];       /* subgroup position limits */
-
+  int    passlimit[8];     /* iteration limit per couple/quant pass */
 } vorbis_info_residue0;
 
 /* Mapping backend generic *****************************************/
@@ -174,7 +176,7 @@
   int   timesubmap[16];    /* [mux] */
   int   floorsubmap[16];   /* [mux] submap to floors */
   int   residuesubmap[16]; /* [mux] submap to residue */
-  int   psysubmap[16];     /* [mux]; encode only */
+  int   psy;               /* encode only */
 
   int   coupling_steps;
   int   coupling_mag[256];

1.8.6.2   +16 -16    vorbis/lib/codec_internal.h

Index: codec_internal.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/codec_internal.h,v
retrieving revision 1.8.6.1
retrieving revision 1.8.6.2
diff -u -r1.8.6.1 -r1.8.6.2
--- codec_internal.h	2001/07/08 08:48:01	1.8.6.1
+++ codec_internal.h	2001/08/02 06:14:44	1.8.6.2
@@ -10,7 +10,7 @@
  ********************************************************************
 
  function: libvorbis codec headers
- last mod: $Id: codec_internal.h,v 1.8.6.1 2001/07/08 08:48:01 xiphmont Exp $
+ last mod: $Id: codec_internal.h,v 1.8.6.2 2001/08/02 06:14:44 xiphmont Exp $
 
  ********************************************************************/
 
@@ -19,8 +19,6 @@
 
 #include "envelope.h"
 #include "codebook.h"
-#include "psy.h"
-#include "bitbuffer.h"
 
 typedef struct vorbis_block_internal{
   float  **pcmdelay;  /* this is a pointer into local storage */ 
@@ -33,6 +31,21 @@
 typedef void vorbis_look_residue;
 typedef void vorbis_look_transform;
 
+/* mode ************************************************************/
+typedef struct {
+  int blockflag;
+  int windowtype;
+  int transformtype;
+  int mapping;
+} vorbis_info_mode;
+
+typedef void vorbis_info_time;
+typedef void vorbis_info_floor;
+typedef void vorbis_info_residue;
+typedef void vorbis_info_mapping;
+
+#include "psy.h"
+
 typedef struct backend_lookup_state {
   /* local lookup storage */
   envelope_lookup        *ve; /* envelope lookup */    
@@ -54,19 +67,6 @@
   unsigned char *header2;
   
 } backend_lookup_state;
-
-/* mode ************************************************************/
-typedef struct {
-  int blockflag;
-  int windowtype;
-  int transformtype;
-  int mapping;
-} vorbis_info_mode;
-
-typedef void vorbis_info_time;
-typedef void vorbis_info_floor;
-typedef void vorbis_info_residue;
-typedef void vorbis_info_mapping;
 
 /* vorbis_info contains all the setup information specific to the
    specific compression/decompression mode in progress (eg,

1.21.2.2  +45 -5     vorbis/lib/psy.h

Index: psy.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/psy.h,v
retrieving revision 1.21.2.1
retrieving revision 1.21.2.2
diff -u -r1.21.2.1 -r1.21.2.2
--- psy.h	2001/07/08 08:48:02	1.21.2.1
+++ psy.h	2001/08/02 06:14:44	1.21.2.2
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: random psychoacoustics (not including preecho)
- last mod: $Id: psy.h,v 1.21.2.1 2001/07/08 08:48:02 xiphmont Exp $
+ last mod: $Id: psy.h,v 1.21.2.2 2001/08/02 06:14:44 xiphmont Exp $
 
  ********************************************************************/
 
@@ -19,6 +19,8 @@
 #define _V_PSY_H_
 #include "smallft.h"
 
+#include "backends.h"
+
 #ifndef EHMER_MAX
 #define EHMER_MAX 56
 #endif
@@ -27,17 +29,37 @@
 #define MAX_BARK 27
 #define P_BANDS 17
 #define P_LEVELS 11
+
+typedef struct vp_couple{
+  int partition_limit;        /* partition post */
+
+  couple_part couple_lossless;
+  couple_part couple_eightphase;
+  couple_part couple_sixphase;
+  couple_part couple_point;
+  
+} vp_couple;
+
+typedef struct vp_couple_pass={
+  float granule;
+  float igranule;
+  
+  vp_couple couple[8];
+} vp_couple_pass;
+
 typedef struct vorbis_info_psy{
   float  *ath;
 
   float  ath_adjatt;
   float  ath_maxatt;
+  float  floor_masteratt;
 
   /*     0  1  2   3   4   5   6   7   8   9  10  11  12  13  14  15   16   */
   /* x: 63 88 125 175 250 350 500 700 1k 1.4k 2k 2.8k 4k 5.6k 8k 11.5k 16k Hz */
   /* y: 0 10 20 30 40 50 60 70 80 90 100 dB */
 
   int tonemaskp;
+  float tone_masteratt;
   float toneatt[P_BANDS][P_LEVELS];
 
   int peakattp;
@@ -53,8 +75,10 @@
   float noisemedian[P_BANDS*2];
 
   float max_curve_dB;
-  float bound_att_dB;
 
+  int coupling_passes;
+  vp_couple_pass *couple_pass;
+
 } vorbis_info_psy;
 
 typedef struct{
@@ -72,7 +96,6 @@
   /* delay caching... how many samples to keep around prior to our
      current block to aid in analysis? */
   int       delaycache;
-
 } vorbis_info_psy_global;
 
 typedef struct {
@@ -112,16 +135,33 @@
 
 extern void   _vi_psy_free(vorbis_info_psy *i);
 extern vorbis_info_psy *_vi_psy_copy(vorbis_info_psy *i);
+
+extern void _vp_remove_floor(vorbis_look_psy *p,
+			     vorbis_look_psy_global *g,
+			     float *logmdct, 
+			     float *mdct,
+			     float *codedflr,
+			     float *residue,
+			     float local_specmax);
 
-extern float  _vp_compute_mask(vorbis_look_psy *p,
+extern void   _vp_compute_mask(vorbis_look_psy *p,
                                vorbis_look_psy_global *g,
                                int channel,
                                float *fft, 
                                float *mdct, 
                                float *mask, 
-			       float specmax,
+			       float global_specmax,
+			       float local_specmax,
                                int lastsize);
 
+extern void _vp_partition_prequant(vorbis_look_psy *p,
+				   vorbis_info *vi,
+				   float **vbpcm,
+				   int *nonzero);
+extern void _vp_couple(vorbis_look_psy *p,
+		       vorbis_info_mapping0 *vi,
+		       float **vbpcm,
+		       int *nonzero);
 
 extern float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd);
 

1.7.2.1   +1 -3      vorbis/lib/registry.h

Index: registry.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/registry.h,v
retrieving revision 1.7
retrieving revision 1.7.2.1
diff -u -r1.7 -r1.7.2.1
--- registry.h	2001/06/15 21:15:40	1.7
+++ registry.h	2001/08/02 06:14:45	1.7.2.1
@@ -11,14 +11,12 @@
  ********************************************************************
 
  function: registry for time, floor, res backends and channel mappings
- last mod: $Id: registry.h,v 1.7 2001/06/15 21:15:40 xiphmont Exp $
+ last mod: $Id: registry.h,v 1.7.2.1 2001/08/02 06:14:45 xiphmont Exp $
 
  ********************************************************************/
 
 #ifndef _V_REG_H_
 #define _V_REG_H_
-
-#include "backends.h"
 
 #define VI_TRANSFORMB 1
 #define VI_WINDOWB 1

--- >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