Collect training data from the lib when compiled with -DTRAIN
authorMonty <xiphmont@xiph.org>
Sat, 12 Feb 2000 08:33:10 +0000 (08:33 +0000)
committerMonty <xiphmont@xiph.org>
Sat, 12 Feb 2000 08:33:10 +0000 (08:33 +0000)
Added staging to floor0.c
Added first work toward residue partitioning and huff builder

Monty
x

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

15 files changed:
Makefile.in
configure
configure.in
examples/Makefile.in
include/vorbis/backends.h
include/vorbis/codec.h
include/vorbis/modes.h
lib/analysis.c
lib/floor0.c
lib/mapping0.c
lib/psy.c
lib/psy.h
lib/res0.c
lib/synthesis.c
vq/residuesplit.c [new file with mode: 0644]

index 9dd4b1d..b2fea18 100644 (file)
@@ -1,6 +1,6 @@
 # vorbis makefile configured for use with gcc on any platform
 
-# $Id: Makefile.in,v 1.4 1999/12/30 07:26:22 xiphmont Exp $
+# $Id: Makefile.in,v 1.5 2000/02/12 08:32:57 xiphmont Exp $
 
 ###############################################################################
 #                                                                             #
@@ -17,7 +17,7 @@
 
 @SET_MAKE@
 
-SUBDIRS =      lib vq examples # cmdline xmms
+SUBDIRS =      lib vq huff examples # cmdline xmms
 
 all debug profile selftest target clean:
        @for dir in $(SUBDIRS); do (cd $$dir && $(MAKE) $(MFLAGS) $@) || exit 1; done
index 71c1d7d..cdefa9e 100755 (executable)
--- a/configure
+++ b/configure
@@ -2117,7 +2117,7 @@ done
 
 ac_given_srcdir=$srcdir
 
-trap 'rm -fr `echo "Makefile lib/Makefile examples/Makefile vq/Makefile cmdline/Makefile xmms/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+trap 'rm -fr `echo "Makefile lib/Makefile examples/Makefile vq/Makefile huff/Makefile cmdline/Makefile xmms/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
 
@@ -2206,7 +2206,7 @@ EOF
 
 cat >> $CONFIG_STATUS <<EOF
 
-CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile examples/Makefile vq/Makefile cmdline/Makefile xmms/Makefile"}
+CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile examples/Makefile vq/Makefile huff/Makefile cmdline/Makefile xmms/Makefile"}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
index d330830..42d7b2c 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: configure.in,v 1.9 2000/01/12 11:34:34 xiphmont Exp $
+# $Id: configure.in,v 1.10 2000/02/12 08:32:59 xiphmont Exp $
 
 AC_INIT(lib/mdct.c)
 #AC_CONFIG_HEADER(config.h)
@@ -180,4 +180,4 @@ AC_SUBST(RANLIB)
 #AC_SUBST(LIBGTKDIR)
 AC_SUBST(pthread_lib)
 
-AC_OUTPUT(Makefile lib/Makefile examples/Makefile vq/Makefile cmdline/Makefile xmms/Makefile)
+AC_OUTPUT(Makefile lib/Makefile examples/Makefile vq/Makefile huff/Makefile cmdline/Makefile xmms/Makefile)
index b80ab68..6183a1b 100644 (file)
@@ -1,6 +1,6 @@
 # vorbis makefile configured for use with gcc on any platform
 
-# $Id: Makefile.in,v 1.4 2000/01/28 09:04:57 xiphmont Exp $
+# $Id: Makefile.in,v 1.5 2000/02/12 08:33:00 xiphmont Exp $
 
 ###############################################################################
 #                                                                             #
@@ -44,6 +44,8 @@ profile:
 
 target:        $(BINFILES)
 
+encoder_example.o:     ../include/vorbis/modes.h
+
 encoder_example:       $(OFILES) ../lib/libvorbis.a
        $(CC) $(CFLAGS) $(LDFLAGS) encoder_example.o ../lib/libvorbis.a -o \
                        encoder_example -lm
index 5030de5..d24a364 100644 (file)
@@ -13,7 +13,7 @@
 
  function: libvorbis backend and mapping structures; needed for 
            static mode headers
- last mod: $Id: backends.h,v 1.5 2000/02/09 22:04:09 xiphmont Exp $
+ last mod: $Id: backends.h,v 1.6 2000/02/12 08:33:01 xiphmont Exp $
 
  ********************************************************************/
 
@@ -83,7 +83,7 @@ typedef struct{
   void (*free_info)    (vorbis_info_residue *);
   void (*free_look)    (vorbis_look_residue *);
   int  (*forward)      (struct vorbis_block *,vorbis_look_residue *,
-                       double **,int **,int);
+                       double **,int);
   int  (*inverse)      (struct vorbis_block *,vorbis_look_residue *,
                        double **,int);
 } vorbis_func_residue;
@@ -93,7 +93,13 @@ typedef struct vorbis_info_residue0{
   long  begin;
   long  end;
 
-  /* way unfinished, just so you know while poking around CVS ;-) */
+  /* first stage (lossless partitioning) */
+  int grouping;         /* group n vectors */
+  int partitions;       /* partition entries (per group) */
+  int groupspercode;    /* groups per codeword */
+  int groupbook;        /* huffbook for partitioning */
+  int secondstages[64]; /* expanded out to pointers in lookup */
+  int booklist[256];    /* list of second stage books */
 
 } vorbis_info_residue0;
 
index aa05234..703da9f 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: libvorbis codec headers
- last mod: $Id: codec.h,v 1.8 2000/02/06 13:39:37 xiphmont Exp $
+ last mod: $Id: codec.h,v 1.9 2000/02/12 08:33:02 xiphmont Exp $
 
  ********************************************************************/
 
@@ -269,6 +269,7 @@ typedef struct vorbis_block{
   long  W;
   long  nW;
   int   pcmend;
+  int   mode;
 
   int eofflag;
   int frameno;
index 06ee1af..b213666 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: modes.h,v 1.5 2000/02/09 22:04:10 xiphmont Exp $
+ last mod: $Id: modes.h,v 1.6 2000/02/12 08:33:03 xiphmont Exp $
 
  ********************************************************************/
 
@@ -46,9 +46,10 @@ static vorbis_info_psy _psy_set0={
 static vorbis_info_time0 _time_set0={0};
 static vorbis_info_floor0 _floor_set0={20, 44100,  64, 12,140, 1, {0} };
 static vorbis_info_floor0 _floor_set1={32, 44100, 256, 12,140, 1, {1} };
-static vorbis_info_residue0 _residue_set0={0,0};
+static vorbis_info_residue0 _residue_set0={0, 128, 32,4,4,3,{0,1,1,1},{0,0,0}};
+static vorbis_info_residue0 _residue_set1={0,1024, 32,4,4,3,{0,1,1,1},{0,0,0}};
 static vorbis_info_mapping0 _mapping_set0={1, {0,0}, {0}, {0}, {0}, {0}};
-static vorbis_info_mapping0 _mapping_set1={1, {0,0}, {0}, {1}, {0}, {0}};
+static vorbis_info_mapping0 _mapping_set1={1, {0,0}, {0}, {1}, {1}, {0}};
 static vorbis_info_mode _mode_set0={0,0,0,0};
 static vorbis_info_mode _mode_set1={1,0,0,1};
 
@@ -69,7 +70,7 @@ vorbis_info info_A={
   /* floors */
   {0,0},{&_floor_set0,&_floor_set1},
   /* residue */
-  {0,0},{&_residue_set0},
+  {0,0},{&_residue_set0,&_residue_set1},
   /* books */
   {&_vq_book_lsp20_0,&_vq_book_lsp32_0},
   /* psy */
index faceac3..c6fd420 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: single-block PCM analysis mode dispatch
- last mod: $Id: analysis.c,v 1.22 2000/01/22 13:28:14 xiphmont Exp $
+ last mod: $Id: analysis.c,v 1.23 2000/02/12 08:33:04 xiphmont Exp $
 
  ********************************************************************/
 
@@ -44,6 +44,7 @@ int vorbis_analysis(vorbis_block *vb,ogg_packet *op){
 
   if(vb->W &&vi->modes>1)mode=1;
   type=vi->map_type[vi->mode_param[mode]->mapping];
+  vb->mode=mode;
 
   /* Encode frame mode, pre,post windowsize, then dispatch */
   _oggpack_write(&vb->opb,mode,vd->modebits);
index 56ef805..eff41a4 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: floor backend 0 implementation
- last mod: $Id: floor0.c,v 1.8 2000/02/09 22:04:12 xiphmont Exp $
+ last mod: $Id: floor0.c,v 1.9 2000/02/12 08:33:05 xiphmont Exp $
 
  ********************************************************************/
 
@@ -143,6 +143,20 @@ static int forward(vorbis_block *vb,vorbis_look_floor *i,
     vorbis_lpc_to_lsp(out,out,look->m);
     memcpy(work,out,sizeof(double)*look->m);
 
+#ifdef TRAIN
+    {
+      int j;
+      FILE *of;
+      char buffer[80];
+      sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
+      of=fopen(buffer,"a");
+      for(j=0;j<look->m;j++)
+       fprintf(of,"%g, ",out[j]);
+      fprintf(of,"\n");
+      fclose(of);
+    }
+#endif
+
     /* code the spectral envelope, and keep track of the actual
        quantized values; we don't want creeping error as each block is
        nailed to the last quantized value of the previous block. */
index 58f6f13..df36ce5 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: channel mapping 0 implementation
- last mod: $Id: mapping0.c,v 1.8 2000/02/09 22:04:14 xiphmont Exp $
+ last mod: $Id: mapping0.c,v 1.9 2000/02/12 08:33:06 xiphmont Exp $
 
  ********************************************************************/
 
@@ -190,7 +190,6 @@ static int forward(vorbis_block *vb,vorbis_look_mapping *l){
   double *window=vd->window[vb->W][vb->lW][vb->nW][mode->windowtype];
 
   double **pcmbundle=alloca(sizeof(double *)*vi->channels);
-  int **auxbundle=alloca(sizeof(int *)*vi->channels);
   int *nonzero=alloca(sizeof(int)*vi->channels);
   
   /* time domain pre-window: NONE IMPLEMENTED */
@@ -216,19 +215,17 @@ static int forward(vorbis_block *vb,vorbis_look_mapping *l){
     double *decfloor=_vorbis_block_alloc(vb,n*sizeof(double)/2);
     double *floor=_vorbis_block_alloc(vb,n*sizeof(double)/2);
     double *mask=_vorbis_block_alloc(vb,n*sizeof(double)/2);
-    int **pcmaux=_vorbis_block_alloc(vb,vi->channels*sizeof(int *));
     
     for(i=0;i<vi->channels;i++){
       double *pcm=vb->pcm[i];
       int submap=map->chmuxlist[i];
 
-      pcmaux[i]=_vorbis_block_alloc(vb,n/2*sizeof(int));
       /* perform psychoacoustics; takes PCM vector; 
         returns two curves: the desired transform floor and the masking curve */
       memset(floor,0,sizeof(double)*n/2);
       memset(mask,0,sizeof(double)*n/2);
-      _vp_mask_floor(look->psy_look+submap,pcm,mask,floor);
+      _vp_mask_floor(look->psy_look+submap,pcm,floor,0);
+      _vp_mask_floor(look->psy_look+submap,pcm,mask,1);
  
       /* perform floor encoding; takes transform floor, returns decoded floor */
       nonzero[i]=look->floor_func[submap]->
@@ -236,12 +233,28 @@ static int forward(vorbis_block *vb,vorbis_look_mapping *l){
       
       /* no iterative residue/floor tuning at the moment */
       
-      /* perform residue prequantization.  Do it now so we have all
-         the values if we need them */
-      _vp_quantize(look->psy_look+submap,pcm,mask,decfloor,pcmaux[i],0,n/2,n/2);
-      
+#ifdef TRAIN
+      if(nonzero[i]){
+       FILE *of;
+       char buffer[80];
+       
+       sprintf(buffer,"masked_%d.vqd",vb->mode);
+       of=fopen(buffer,"a");
+       for(i=0;i<n/2;i++)
+         fprintf(of,"%g, ",pcm[i]/mask[i]);
+       fprintf(of,"\n");
+       fclose(of);
+       sprintf(buffer,"floored_%d.vqd",vb->mode);
+       of=fopen(buffer,"a");
+       for(i=0;i<n/2;i++)
+         fprintf(of,"%g, ",pcm[i]/floor[i]);
+       fprintf(of,"\n");
+       fclose(of);
+      }
+#endif      
+
     }
-  
+    
     /* perform residue encoding with residue mapping; this is
        multiplexed.  All the channels belonging to one submap are
        encoded (values interleaved), then the next submap, etc */
@@ -251,12 +264,11 @@ static int forward(vorbis_block *vb,vorbis_look_mapping *l){
       for(j=0;j<vi->channels;j++){
        if(map->chmuxlist[j]==i && nonzero[j]==1){
          pcmbundle[ch_in_bundle]=vb->pcm[j];
-         auxbundle[ch_in_bundle++]=pcmaux[j];
        }
       }
       
-      look->residue_func[i]->forward(vb,look->residue_look[i],pcmbundle,auxbundle,
-                                ch_in_bundle);
+      look->residue_func[i]->forward(vb,look->residue_look[i],
+                                    pcmbundle,ch_in_bundle);
     }
   }
 
index 1b9b5fb..dd6a10e 100644 (file)
--- a/lib/psy.c
+++ b/lib/psy.c
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: psychoacoustics not including preecho
- last mod: $Id: psy.c,v 1.15 2000/02/06 13:39:44 xiphmont Exp $
+ last mod: $Id: psy.c,v 1.16 2000/02/12 08:33:07 xiphmont Exp $
 
  ********************************************************************/
 
@@ -84,18 +84,18 @@ void _vp_psy_clear(vorbis_look_psy *p){
 
 /* Masking curve: linear rolloff on a Bark/dB scale, attenuated by
    maskthresh */
-/* right now, floor==mask */
-void _vp_mask_floor(vorbis_look_psy *p,double *f, double *mask,double *floor){
+
+void _vp_mask_floor(vorbis_look_psy *p,double *f, double *floor,int attp){
   int n=p->n;
   double hroll=p->vi->hrolldB;
   double lroll=p->vi->lrolldB;
-  double curmask=todB(f[0])+p->maskthresh[0];
+  double curmask=todB(f[0])+(attp?p->maskthresh[0]:0);
   double curoc=0.;
   long i;
 
   /* run mask forward then backward */
   for(i=0;i<n;i++){
-    double newmask=todB(f[i])+p->maskthresh[i];
+    double newmask=todB(f[i])+(attp?p->maskthresh[i]:0);
     double newoc=p->barknum[i];
     double roll=curmask-(newoc-curoc)*hroll;
     double troll;
@@ -104,14 +104,13 @@ void _vp_mask_floor(vorbis_look_psy *p,double *f, double *mask,double *floor){
       curoc=newoc;
     }
     troll=fromdB(roll);
-    if(mask[i]<troll)mask[i]=troll;
     if(floor[i]<troll)floor[i]=troll;
   }
 
-  curmask=todB(f[n-1])+p->maskthresh[n-1];
+  curmask=todB(f[n-1])+(attp?p->maskthresh[n-1]:0);
   curoc=p->barknum[n-1];
   for(i=n-1;i>=0;i--){
-    double newmask=todB(f[i])+p->maskthresh[i];
+    double newmask=todB(f[i])+(attp?p->maskthresh[i]:0);
     double newoc=p->barknum[i];
     double roll=curmask-(curoc-newoc)*lroll;
     double troll;
@@ -120,34 +119,10 @@ void _vp_mask_floor(vorbis_look_psy *p,double *f, double *mask,double *floor){
       curoc=newoc;
     }
     troll=fromdB(roll);
-    if(mask[i]<troll)mask[i]=troll;
     if(floor[i]<troll)floor[i]=troll;
   }
 }
 
-/* take a masking curve and raw residue; eliminate the inaduble and
-   quantize to the final form handed to the VQ.  All and any tricks to
-   squeeze out bits given knowledge of the encoding mode should go
-   here too */
-
-/* modifies the pcm vector, returns book membership in aux */
-
-void _vp_quantize(vorbis_look_psy *p, double *pcm, double *mask, 
-                 double *floor,int *aux,long begin, long n,long subn){
-  long i,j;
-    /* for now, we're not worrying about subvector, but the idea is
-       that we normal blocks not have zeroes; zeroes only exist as an
-       all-zero block */
-
-  for(i=begin;i<n;i++){
-    double value=rint(pcm[i]/floor[i]);
-    if(value>15)value=15;
-    if(value<-15)value=-15;
-    pcm[i]=value;
-  }
-
-}
-
 /* s must be padded at the end with m-1 zeroes */
 static void time_convolve(double *s,double *r,int n,int m){
   int i;
index 6426f94..5f41163 100644 (file)
--- a/lib/psy.h
+++ b/lib/psy.h
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: random psychoacoustics (not including preecho)
- last mod: $Id: psy.h,v 1.10 2000/02/06 13:39:45 xiphmont Exp $
+ last mod: $Id: psy.h,v 1.11 2000/02/12 08:33:08 xiphmont Exp $
 
  ********************************************************************/
 
@@ -26,13 +26,6 @@ typedef struct {
   double *maskthresh;
   double *barknum;
 
-  int    framebegin;
-  int    frameend;
-  int    subframelen;
-  int    elements[4];
-  double cutoffs[4];
-  int    quantval[4];
-
 } vorbis_look_psy;
 
 extern void   _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate);
@@ -40,11 +33,8 @@ extern void   _vp_psy_clear(vorbis_look_psy *p);
 extern void  *_vi_psy_dup(void *source);
 extern void   _vi_psy_free(vorbis_info_psy *i);
 
-extern void   _vp_mask_floor(vorbis_look_psy *p,double *pcm,
-                            double *mask,double *floor);
-extern void   _vp_quantize(vorbis_look_psy *p, double *pcm, double *mask, 
-                          double *floor,int *aux,
-                          long begin,long n, long subn);
+extern void   _vp_mask_floor(vorbis_look_psy *p,double *pcm,double *floor,
+                            int attp);
 #endif
 
 
index 65012fd..ec0b27c 100644 (file)
  ********************************************************************
 
  function: residue backend 0 implementation
- last mod: $Id: res0.c,v 1.4 2000/02/06 13:39:46 xiphmont Exp $
+ last mod: $Id: res0.c,v 1.5 2000/02/12 08:33:09 xiphmont Exp $
 
  ********************************************************************/
 
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
+#include <stdio.h>
 #include "vorbis/codec.h"
 #include "bitwise.h"
 #include "registry.h"
+#include "scales.h"
 
-/* unfinished as of 20000118 */
+typedef struct {
+  vorbis_info_residue0 *info;
+  int bookpointers[64];
+} vorbis_look_residue0;
 
 void free_info(vorbis_info_residue *i){
+  if(i){
+    memset(i,0,sizeof(vorbis_info_residue0));
+    free(i);
+  }
 }
 
 void free_look(vorbis_look_residue *i){
+  if(i){
+    memset(i,0,sizeof(vorbis_look_residue0));
+    free(i);
+  }
 }
 
 /* not yet */
 void pack(vorbis_info_residue *vr,oggpack_buffer *opb){
+  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
+  int j,acc=0;
+  _oggpack_write(opb,info->begin,24);
+  _oggpack_write(opb,info->end,24);
+
+  _oggpack_write(opb,info->grouping-1,24);  /* residue vectors to group and 
+                                            code with a partitioned book */
+  _oggpack_write(opb,info->partitions-1,6); /* possible partition choices */
+  _oggpack_write(opb,info->groupspercode-1,6); /* partitioned group
+                                                codes to encode at
+                                                once */
+  _oggpack_write(opb,info->groupbook,8);  /* group huffman book */
+  for(j=0;j<info->partitions;j++){
+    _oggpack_write(opb,info->secondstages[j],4); /* zero *is* a valid choice */
+    acc+=info->secondstages[j];
+  }
+  for(j=0;j<acc;j++)
+    _oggpack_write(opb,info->booklist[j],8);
+
 }
 
 /* vorbis_info is for range checking */
 vorbis_info_residue *unpack(vorbis_info *vi,oggpack_buffer *opb){
-  return "";
+  int j,acc=0;
+  vorbis_info_residue0 *ret=calloc(1,sizeof(vorbis_info_residue0));
+
+  ret->begin=_oggpack_read(opb,24);
+  ret->end=_oggpack_read(opb,24);
+  ret->grouping=_oggpack_read(opb,24)+1;
+  ret->partitions=_oggpack_read(opb,6)+1;
+  ret->groupspercode=_oggpack_read(opb,6)+1;
+  ret->groupbook=_oggpack_read(opb,8);
+  for(j=0;j<ret->partitions;j++)
+    acc+=ret->secondstages[j]=_oggpack_read(opb,4);
+  for(j=0;j<acc;j++)
+    ret->booklist[j]=_oggpack_read(opb,8);
+
+  if(ret->groupbook>=vi->books)goto errout;
+  for(j=0;j<acc;j++)
+    if(ret->booklist[j]>=vi->books)goto errout;
+
+  return(ret);
+ errout:
+  free_info(ret);
+  return(NULL);
 }
 
 vorbis_look_residue *look (vorbis_info *vi,vorbis_info_mode *vm,
                          vorbis_info_residue *vr){
-  return "";
+  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
+  vorbis_look_residue0 *look=calloc(1,sizeof(vorbis_look_residue0));
+  int j,acc=0;
+  look->info=info;
+  for(j=0;j<info->partitions;j++){
+    look->bookpointers[j]=acc;
+    acc+=info->secondstages[j];
+  }
+
+  return(look);
 }
 
 int forward(vorbis_block *vb,vorbis_look_residue *l,
-           double **in,int **aux,int ch){
+           double **in,int ch){
   long i,j;
+  vorbis_look_residue0 *look=(vorbis_look_residue0 *)l;
+  vorbis_info_residue0 *info=look->info;
   for(i=0;i<ch;i++)
     for(j=0;j<vb->pcmend/2;j++)
       _oggpack_write(&vb->opb,rint(in[i][j])+16,5);
index 3947f23..031d6cd 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: single-block PCM synthesis
- last mod: $Id: synthesis.c,v 1.14 2000/01/22 13:28:33 xiphmont Exp $
+ last mod: $Id: synthesis.c,v 1.15 2000/02/12 08:33:10 xiphmont Exp $
 
  ********************************************************************/
 
@@ -40,6 +40,7 @@ int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
 
   /* read our mode and pre/post windowsize */
   mode=_oggpack_read(opb,vd->modebits);
+  vb->mode=mode;
   vb->W=vi->mode_param[mode]->blockflag;
   if(vb->W){
     vb->lW=_oggpack_read(opb,1);
diff --git a/vq/residuesplit.c b/vq/residuesplit.c
new file mode 100644 (file)
index 0000000..28205f1
--- /dev/null
@@ -0,0 +1,230 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
+ * PLEASE READ THESE TERMS DISTRIBUTING.                            *
+ *                                                                  *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
+ * http://www.xiph.org/                                             *
+ *                                                                  *
+ ********************************************************************
+
+ function: residue backend 0 partitioner
+ last mod: $Id: residuesplit.c,v 1.1 2000/02/12 08:33:01 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+#include "../lib/scales.h"
+#include "../vq/bookutil.h"
+
+/* take a masking curve and raw residue; eliminate the inaduble and
+   quantize to the final form handed to the VQ.  All and any tricks to
+   squeeze out bits given knowledge of the encoding mode should go
+   here too */
+
+/* modifies the pcm vector, returns book membership in aux */
+
+/* This is currently a bit specific to/hardwired for mapping 0; things
+   will need to change in the future when we het real multichannel
+   mappings */
+
+static double _maxval(double *v,int n){
+  int i;
+  double acc=0.;
+  for(i=0;i<n;i++){
+    double val=fabs(v[i]);
+    if(acc<val)acc=val;
+  }
+  return(acc);
+}
+
+/* mean dB actually */
+static double _meanval(double *v,int n){
+  int i;
+  double acc=0.;
+  for(i=0;i<n;i++)
+    acc+=todB(fabs(v[i]));
+  return(fromdB(acc/n));
+}
+
+static FILE *of;
+static FILE **or;
+
+int quantaux(double *mask, double *floor,int n,
+            double *maskmbound,double *maskabound,double *floorbound,
+            int parts, int subn){
+  long i,j;
+
+  for(i=0;i<=n-subn;){
+    double maxmask=_maxval(mask+i,subn);
+    double meanmask=_meanval(mask+i,subn);
+    double meanfloor=_meanval(floor+i,subn);
+    int aux;
+
+    for(j=0;j<parts-1;j++)
+      if(maxmask<maskmbound[j] && 
+        meanmask<maskabound[j] &&
+        meanfloor<floorbound[j])
+       break;
+    aux=j;
+
+    fprintf(of,"%d, ",aux);      
+
+    for(j=0;j<subn;j++,i++)
+      fprintf(or[aux],"%g, ",floor[i]);
+    fprintf(or[aux],"\n");
+  }
+
+  fprintf(of,"\n");
+
+  return(0);
+}
+
+static int getline(FILE *in,double *vec,int begin,int n){
+  int i,next=0;
+
+  reset_next_value();
+  if(get_next_value(in,vec))return(0);
+  if(begin){
+    for(i=1;i<begin;i++)
+      get_line_value(in,vec);
+    next=0;
+  }else{
+    next=1;
+  }
+
+  for(i=next;i<n;i++)
+    if(get_line_value(in,vec+i)){
+      fprintf(stderr,"ran out of columns in input data\n");
+      exit(1);
+    }
+  
+  return(1);
+}
+
+static void usage(){
+  fprintf(stderr,
+         "usage:\n" 
+         "residuesplit <mask> <floor> <begin,n,group> <baseout> <m,a,f> [<m,a,f>]...\n"
+         "   where begin,n,group is first scalar, \n"
+         "                          number of scalars of each in line,\n"
+         "                          number of scalars in a group\n"
+         "         m,a,f are the boundary conditions for each group\n"
+         "eg: residuesplit mask.vqd floor.vqd 0,1024,32 res .5 2.5,1.5 ,,.25\n"
+         "produces resaux.vqd and res_0...n.vqd\n\n");
+  exit(1);
+}
+
+int main(int argc, char *argv[]){
+  char *buffer;
+  char *base;
+  int i,parts,begin,n,subn;
+  FILE *mask;
+  FILE *floor;
+  double *maskmbound,*maskabound,*maskvec;
+  double *floorbound,*floorvec;
+
+  if(argc<6)usage();
+
+  base=strdup(argv[4]);
+  buffer=alloca(strlen(base)+20);
+  {
+    char *pos=strchr(argv[3],',');
+    begin=atoi(argv[3]);
+    if(!pos)
+      usage();
+    else
+      n=atoi(pos+1);
+    pos=strchr(pos+1,',');
+    if(!pos)
+      usage();
+    else
+      subn=atoi(pos+1);
+    if(n/subn*subn != n){
+      fprintf(stderr,"n must be divisible by group\n");
+      exit(1);
+    }
+  }
+
+  /* how many parts?  Need to scan m,f... */
+  parts=argc-4; /* yes, one past */
+  maskmbound=malloc(sizeof(double)*parts);
+  maskabound=malloc(sizeof(double)*parts);
+  floorbound=malloc(sizeof(double)*parts);
+
+  for(i=0;i<parts-1;i++){
+    char *pos=strchr(argv[5+i],',');
+    maskmbound[i]=atof(argv[5+i]);
+    if(*argv[5+i]==',')maskmbound[i]=1e50;
+    if(!pos){
+      maskabound[i]=1e50;
+      floorbound[i]=1e50;
+    }else{
+      maskabound[i]=atof(pos+1);
+      if(pos[1]==',')maskabound[i]=1e50;
+      pos=strchr(pos+1,',');
+      if(!pos)
+       floorbound[i]=1e50;
+      else{
+       floorbound[i]=atof(pos+1);
+      }
+    }
+  }
+  maskmbound[i]=1e50;
+  maskabound[i]=1e50;
+  floorbound[i]=1e50;
+
+  mask=fopen(argv[1],"r");
+  if(!mask){
+    fprintf(stderr,"Could not open file %s\n",argv[1]);
+    exit(1);
+  }
+  floor=fopen(argv[2],"r");
+  if(!mask){
+    fprintf(stderr,"Could not open file %s\n",argv[2]);
+    exit(1);
+  }
+
+  or=alloca(parts*sizeof(FILE*));
+  sprintf(buffer,"%saux.vqd",base);
+  of=fopen(buffer,"w");
+  if(!of){
+    fprintf(stderr,"Could not open file %s for writing\n",buffer);
+    exit(1);
+  }
+  for(i=0;i<parts;i++){
+    sprintf(buffer,"%s_%d.vqd",base,i);
+    or[i]=fopen(buffer,"w");
+    if(!or[i]){
+      fprintf(stderr,"Could not open file %s for writing\n",buffer);
+      exit(1);
+    }
+  }
+  
+  maskvec=malloc(sizeof(double)*n);
+  floorvec=malloc(sizeof(double)*n);
+  /* get the input line by line and process it */
+  while(!feof(mask) && !feof(floor)){
+    if(getline(mask,maskvec,begin,n) &&
+       getline(floor,floorvec,begin,n)) 
+      quantaux(maskvec,floorvec,n,
+              maskmbound,maskabound,floorbound,parts,subn);
+    
+  }
+  fclose(mask);
+  fclose(floor);
+  fclose(of);
+  for(i=0;i<parts;i++)
+    fclose(or[i]);
+  return(0);
+}
+
+
+
+