examples/SFExamples/oggvorbiscodec/src/libvorbis/vq/latticebuild.c

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
00004  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00005  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00006  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00007  *                                                                  *
00008  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
00009  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
00010  *                                                                  *
00011  ********************************************************************
00012 
00013  function: utility main for building codebooks from lattice descriptions
00014  last mod: $Id: latticebuild.c 7187 2004-07-20 07:24:27Z xiphmont $
00015 
00016  ********************************************************************/
00017 
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <math.h>
00021 #include <string.h>
00022 #include <errno.h>
00023 #include "bookutil.h"
00024 
00025 /* The purpose of this util is just to finish packaging the
00026    description into a static codebook.  It used to count hits for a
00027    histogram, but I've divorced that out to add some flexibility (it
00028    currently generates an equal probability codebook) 
00029 
00030    command line:
00031    latticebuild description.vql
00032 
00033    the lattice description file contains two lines:
00034 
00035    <n> <dim> <multiplicitavep> <sequentialp>
00036    <value_0> <value_1> <value_2> ... <value_n-1>
00037    
00038    a threshmap (or pigeonmap) struct is generated by latticehint;
00039    there are fun tricks one can do with the threshmap and cascades,
00040    but the utils don't know them...
00041 
00042    entropy encoding is done by feeding an entry list collected from a
00043    training set and feeding it to latticetune along with the book.
00044 
00045    latticebuild produces a codebook on stdout */
00046 
00047 static int ilog(unsigned int v){
00048   int ret=0;
00049   while(v){
00050     ret++;
00051     v>>=1;
00052   }
00053   return(ret);
00054 }
00055 
00056 int main(int argc,char *argv[]){
00057   codebook b;
00058   static_codebook c;
00059   double *quantlist;
00060   long *hits;
00061 
00062   int entries=-1,dim=-1,quantvals=-1,addmul=-1,sequencep=0;
00063   FILE *in=NULL;
00064   char *line,*name;
00065   long i,j;
00066 
00067   memset(&b,0,sizeof(b));
00068   memset(&c,0,sizeof(c));
00069 
00070   if(argv[1]==NULL){
00071     fprintf(stderr,"Need a lattice description file on the command line.\n");
00072     exit(1);
00073   }
00074 
00075   {
00076     char *ptr;
00077     char *filename=_ogg_calloc(strlen(argv[1])+4,1);
00078 
00079     strcpy(filename,argv[1]);
00080     in=fopen(filename,"r");
00081     if(!in){
00082       fprintf(stderr,"Could not open input file %s\n",filename);
00083       exit(1);
00084     }
00085     
00086     ptr=strrchr(filename,'.');
00087     if(ptr){
00088       *ptr='\0';
00089       name=strdup(filename);
00090     }else{
00091       name=strdup(filename);
00092     }
00093 
00094   }
00095   
00096   /* read the description */
00097   line=get_line(in);
00098   if(sscanf(line,"%d %d %d %d",&quantvals,&dim,&addmul,&sequencep)!=4){
00099     if(sscanf(line,"%d %d %d",&quantvals,&dim,&addmul)!=3){
00100       fprintf(stderr,"Syntax error reading description file (line 1)\n");
00101       exit(1);
00102     }
00103   }
00104   entries=pow(quantvals,dim);
00105   c.dim=dim;
00106   c.entries=entries;
00107   c.lengthlist=_ogg_malloc(entries*sizeof(long));
00108   c.maptype=1;
00109   c.q_sequencep=sequencep;
00110   c.quantlist=_ogg_calloc(quantvals,sizeof(long));
00111 
00112   quantlist=_ogg_malloc(sizeof(double)*c.dim*c.entries);
00113   hits=_ogg_malloc(c.entries*sizeof(long));
00114   for(j=0;j<entries;j++)hits[j]=1;
00115   for(j=0;j<entries;j++)c.lengthlist[j]=1;
00116 
00117   reset_next_value();
00118   line=setup_line(in);
00119   for(j=0;j<quantvals;j++){ 
00120     char *temp;
00121     if(!line || sscanf(line,"%lf",quantlist+j)!=1){
00122       fprintf(stderr,"Ran out of data on line 2 of description file\n");
00123       exit(1);
00124     }
00125     temp=strchr(line,',');
00126     if(!temp)temp=strchr(line,' ');
00127     if(temp)temp++;
00128     line=temp;
00129   }
00130 
00131   /* gen a real quant list from the more easily human-grokked input */
00132   {
00133     double min=quantlist[0];
00134     double mindel=-1;
00135     int fac=1;
00136     for(j=1;j<quantvals;j++)if(quantlist[j]<min)min=quantlist[j];
00137     for(j=0;j<quantvals;j++)
00138       for(i=j+1;i<quantvals;i++)
00139         if(mindel==-1 || fabs(quantlist[j]-quantlist[i])<mindel)
00140           mindel=fabs(quantlist[j]-quantlist[i]);
00141 
00142     j=0;
00143     while(j<quantvals){
00144       for(j=0;j<quantvals;j++){
00145         double test=fac*(quantlist[j]-min)/mindel;
00146         if( fabs(rint(test)-test)>.00001f) break;
00147       }
00148       if(fac>100)break;
00149       if(j<quantvals)fac++;
00150     }
00151 
00152     mindel/=fac;
00153     fprintf(stderr,"min=%g mindel=%g\n",min,mindel);
00154 
00155     c.q_min=_float32_pack(min);
00156     c.q_delta=_float32_pack(mindel);
00157     c.q_quant=0;
00158 
00159     min=_float32_unpack(c.q_min);
00160     mindel=_float32_unpack(c.q_delta);
00161     for(j=0;j<quantvals;j++){
00162       c.quantlist[j]=rint((quantlist[j]-min)/mindel);
00163       if(ilog(c.quantlist[j])>c.q_quant)c.q_quant=ilog(c.quantlist[j]);
00164     }
00165   }
00166 
00167   /* build the [default] codeword lengths */
00168   memset(c.lengthlist,0,sizeof(long)*entries);
00169   for(i=0;i<entries;i++)hits[i]=1;
00170   build_tree_from_lengths(entries,hits,c.lengthlist);
00171 
00172   /* save the book in C header form */
00173   write_codebook(stdout,name,&c);
00174   fprintf(stderr,"\r                                                     "
00175           "\nDone.\n");
00176   exit(0);
00177 }

Generated by  doxygen 1.6.2