Update CHANGES for the 1.3.7 release
[platform/upstream/libvorbis.git] / lib / res0.c
index c8e4e78..c931ade 100644 (file)
@@ -5,13 +5,12 @@
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
- * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
+ * by the Xiph.Org Foundation https://xiph.org/                     *
  *                                                                  *
  ********************************************************************
 
  function: residue backend 0, 1 and 2 implementation
- last mod: $Id$
 
  ********************************************************************/
 
@@ -58,6 +57,7 @@ typedef struct {
   float      training_min[8][64];
   float     tmin;
   float     tmax;
+  int       submap;
 #endif
 
 } vorbis_look_residue0;
@@ -88,7 +88,7 @@ void res0_free_look(vorbis_look_residue *i){
             codebook *statebook=look->partbooks[j][k];
 
             /* long and short into the same bucket by current convention */
-            sprintf(buffer,"res_part%d_pass%d.vqd",j,k);
+            sprintf(buffer,"res_sub%d_part%d_pass%d.vqd",look->submap,j,k);
             of=fopen(buffer,"a");
 
             for(l=0;l<statebook->entries;l++)
@@ -148,15 +148,6 @@ void res0_free_look(vorbis_look_residue *i){
   }
 }
 
-static int ilog(unsigned int v){
-  int ret=0;
-  while(v){
-    ret++;
-    v>>=1;
-  }
-  return(ret);
-}
-
 static int icount(unsigned int v){
   int ret=0;
   while(v){
@@ -182,7 +173,7 @@ void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
      bitmask of one indicates this partition class has bits to write
      this pass */
   for(j=0;j<info->partitions;j++){
-    if(ilog(info->secondstages[j])>3){
+    if(ov_ilog(info->secondstages[j])>3){
       /* yes, this is a minor hack due to not thinking ahead */
       oggpack_write(opb,info->secondstages[j],3);
       oggpack_write(opb,1,1);
@@ -246,6 +237,7 @@ vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
     int entries = ci->book_param[info->groupbook]->entries;
     int dim = ci->book_param[info->groupbook]->dim;
     int partvals = 1;
+    if (dim<1) goto errout;
     while(dim>0){
       partvals *= info->partitions;
       if(partvals > entries) goto errout;
@@ -279,7 +271,7 @@ vorbis_look_residue *res0_look(vorbis_dsp_state *vd,
   look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks));
 
   for(j=0;j<look->parts;j++){
-    int stages=ilog(info->secondstages[j]);
+    int stages=ov_ilog(info->secondstages[j]);
     if(stages){
       if(stages>maxstage)maxstage=stages;
       look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j]));
@@ -358,7 +350,7 @@ static int local_book_besterror(codebook *book,int *a){
       if(c->lengthlist[i]>0){
         int this=0;
         for(j=0;j<dim;j++){
-          float val=(e[j]-a[j]);
+          int val=(e[j]-a[j]);
           this+=val*val;
         }
         if(best==-1 || this<best){
@@ -385,8 +377,13 @@ static int local_book_besterror(codebook *book,int *a){
   return(index);
 }
 
+#ifdef TRAIN_RES
 static int _encodepart(oggpack_buffer *opb,int *vec, int n,
                        codebook *book,long *acc){
+#else
+static int _encodepart(oggpack_buffer *opb,int *vec, int n,
+                       codebook *book){
+#endif
   int i,bits=0;
   int dim=book->dim;
   int step=n/dim;
@@ -407,7 +404,7 @@ static int _encodepart(oggpack_buffer *opb,int *vec, int n,
 }
 
 static long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
-                       float **in,int ch){
+                       int **in,int ch){
   long i,j,k;
   vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   vorbis_info_residue0 *info=look->info;
@@ -433,17 +430,17 @@ static long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
   for(i=0;i<partvals;i++){
     int offset=i*samples_per_partition+info->begin;
     for(j=0;j<ch;j++){
-      float max=0.;
-      float ent=0.;
+      int max=0;
+      int ent=0;
       for(k=0;k<samples_per_partition;k++){
-        if(fabs(in[j][offset+k])>max)max=fabs(in[j][offset+k]);
-        ent+=fabs(rint(in[j][offset+k]));
+        if(abs(in[j][offset+k])>max)max=abs(in[j][offset+k]);
+        ent+=abs(in[j][offset+k]);
       }
       ent*=scale;
 
       for(k=0;k<possible_partitions-1;k++)
         if(max<=info->classmetric1[k] &&
-           (info->classmetric2[k]<0 || (int)ent<info->classmetric2[k]))
+           (info->classmetric2[k]<0 || ent<info->classmetric2[k]))
           break;
 
       partword[j][i]=k;
@@ -473,7 +470,7 @@ static long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
 /* designed for stereo or other modes where the partition size is an
    integer multiple of the number of channels encoded in the current
    submap */
-static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,float **in,
+static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,int **in,
                       int ch){
   long i,j,k,l;
   vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
@@ -492,17 +489,17 @@ static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,float **in,
   char buffer[80];
 #endif
 
-  partword[0]=_vorbis_block_alloc(vb,n*ch/samples_per_partition*sizeof(*partword[0]));
-  memset(partword[0],0,n*ch/samples_per_partition*sizeof(*partword[0]));
+  partword[0]=_vorbis_block_alloc(vb,partvals*sizeof(*partword[0]));
+  memset(partword[0],0,partvals*sizeof(*partword[0]));
 
   for(i=0,l=info->begin/ch;i<partvals;i++){
-    float magmax=0.f;
-    float angmax=0.f;
+    int magmax=0;
+    int angmax=0;
     for(j=0;j<samples_per_partition;j+=ch){
-      if(fabs(in[0][l])>magmax)magmax=fabs(in[0][l]);
+      if(abs(in[0][l])>magmax)magmax=abs(in[0][l]);
       for(k=1;k<ch;k++)
-        if(fabs(in[k][l])>angmax)angmax=fabs(in[k][l]);
-        l++;
+        if(abs(in[k][l])>angmax)angmax=abs(in[k][l]);
+      l++;
     }
 
     for(j=0;j<possible_partitions-1;j++)
@@ -529,15 +526,26 @@ static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,float **in,
 }
 
 static int _01forward(oggpack_buffer *opb,
-                      vorbis_block *vb,vorbis_look_residue *vl,
+                      vorbis_look_residue *vl,
                       int **in,int ch,
                       long **partword,
+#ifdef TRAIN_RES
+                      int (*encode)(oggpack_buffer *,int *,int,
+                                    codebook *,long *),
+                      int submap
+#else
                       int (*encode)(oggpack_buffer *,int *,int,
-                                    codebook *,long *)){
+                                    codebook *)
+#endif
+){
   long i,j,k,s;
   vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   vorbis_info_residue0 *info=look->info;
 
+#ifdef TRAIN_RES
+  look->submap=submap;
+#endif
+
   /* move all this setup out later */
   int samples_per_partition=info->grouping;
   int possible_partitions=info->partitions;
@@ -599,13 +607,12 @@ static int _01forward(oggpack_buffer *opb,
             codebook *statebook=look->partbooks[partword[j][i]][s];
             if(statebook){
               int ret;
-              long *accumulator=NULL;
-
 #ifdef TRAIN_RES
+              long *accumulator=NULL;
               accumulator=look->training_data[s][partword[j][i]];
               {
                 int l;
-                float *samples=in[j]+offset;
+                int *samples=in[j]+offset;
                 for(l=0;l<samples_per_partition;l++){
                   if(samples[l]<look->training_min[s][partword[j][i]])
                     look->training_min[s][partword[j][i]]=samples[l];
@@ -613,10 +620,12 @@ static int _01forward(oggpack_buffer *opb,
                     look->training_max[s][partword[j][i]]=samples[l];
                 }
               }
-#endif
-
               ret=encode(opb,in[j]+offset,samples_per_partition,
                          statebook,accumulator);
+#else
+              ret=encode(opb,in[j]+offset,samples_per_partition,
+                         statebook);
+#endif
 
               look->postbits+=ret;
               resbits[partword[j][i]]+=ret;
@@ -627,19 +636,6 @@ static int _01forward(oggpack_buffer *opb,
     }
   }
 
-  /*{
-    long total=0;
-    long totalbits=0;
-    fprintf(stderr,"%d :: ",vb->mode);
-    for(k=0;k<possible_partitions;k++){
-    fprintf(stderr,"%ld/%1.2g, ",resvals[k],(float)resbits[k]/resvals[k]);
-    total+=resvals[k];
-    totalbits+=resbits[k];
-    }
-
-    fprintf(stderr,":: %ld:%1.2g\n",total,(double)totalbits/total);
-    }*/
-
   return(0);
 }
 
@@ -717,21 +713,27 @@ int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
 }
 
 int res1_forward(oggpack_buffer *opb,vorbis_block *vb,vorbis_look_residue *vl,
-                 int **in,int *nonzero,int ch, long **partword){
-  int i,j,used=0,n=vb->pcmend/2;
+                 int **in,int *nonzero,int ch, long **partword, int submap){
+  int i,used=0;
+  (void)vb;
   for(i=0;i<ch;i++)
     if(nonzero[i])
       in[used++]=in[i];
 
   if(used){
-    return _01forward(opb,vb,vl,in,used,partword,_encodepart);
+#ifdef TRAIN_RES
+    return _01forward(opb,vl,in,used,partword,_encodepart,submap);
+#else
+    (void)submap;
+    return _01forward(opb,vl,in,used,partword,_encodepart);
+#endif
   }else{
     return(0);
   }
 }
 
 long **res1_class(vorbis_block *vb,vorbis_look_residue *vl,
-                  float **in,int *nonzero,int ch){
+                  int **in,int *nonzero,int ch){
   int i,used=0;
   for(i=0;i<ch;i++)
     if(nonzero[i])
@@ -755,7 +757,7 @@ int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
 }
 
 long **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
-                  float **in,int *nonzero,int ch){
+                  int **in,int *nonzero,int ch){
   int i,used=0;
   for(i=0;i<ch;i++)
     if(nonzero[i])used++;
@@ -770,7 +772,7 @@ long **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
 
 int res2_forward(oggpack_buffer *opb,
                  vorbis_block *vb,vorbis_look_residue *vl,
-                 int **in,int *nonzero,int ch, long **partword){
+                 int **in,int *nonzero,int ch, long **partword,int submap){
   long i,j,k,n=vb->pcmend/2,used=0;
 
   /* don't duplicate the code; use a working vector hack for now and
@@ -785,7 +787,12 @@ int res2_forward(oggpack_buffer *opb,
   }
 
   if(used){
-    return _01forward(opb,vb,vl,&work,1,partword,_encodepart);
+#ifdef TRAIN_RES
+    return _01forward(opb,vl,&work,1,partword,_encodepart,submap);
+#else
+    (void)submap;
+    return _01forward(opb,vl,&work,1,partword,_encodepart);
+#endif
   }else{
     return(0);
   }
@@ -819,7 +826,7 @@ int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
         if(s==0){
           /* fetch the partition word */
           int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
-          if(temp==-1 || temp>info->partvals)goto eopbreak;
+          if(temp==-1 || temp>=info->partvals)goto eopbreak;
           partword[l]=look->decodemap[temp];
           if(partword[l]==NULL)goto errout;
         }