Incremental update
[platform/upstream/libvorbis.git] / vq / run.c
1 #include "lsp16.vqh"
2 #define CODEBOOK _vq_book_lsp16
3
4 /********************************************************************
5  *                                                                  *
6  * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
7  * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
8  * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
9  * PLEASE READ THESE TERMS DISTRIBUTING.                            *
10  *                                                                  *
11  * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999             *
12  * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company       *
13  * http://www.xiph.org/                                             *
14  *                                                                  *
15  ********************************************************************
16
17  function: utility main for loading/testing/running finished codebooks
18  author: Monty <xiphmont@mit.edu>
19  modifications by: Monty
20  last modification date: Dec 28 1999
21
22  ********************************************************************/
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <math.h>
27 #include <string.h>
28 #include <errno.h>
29
30 /* this is a bit silly; it's a C stub used by a Perl script to build a
31    quick executable against the chosen codebook and run tests */
32
33 static char *linebuffer=NULL;
34 static int  lbufsize=0;
35 static char *rline(FILE *in){
36   long sofar=0;
37   if(feof(in))return NULL;
38
39   while(1){
40     int gotline=0;
41
42     while(!gotline){
43       if(sofar>=lbufsize){
44         if(!lbufsize){  
45           lbufsize=1024;
46           linebuffer=malloc(lbufsize);
47         }else{
48           lbufsize*=2;
49           linebuffer=realloc(linebuffer,lbufsize);
50         }
51       }
52       {
53         long c=fgetc(in);
54         switch(c){
55         case '\n':
56         case EOF:
57           gotline=1;
58           break;
59         default:
60           linebuffer[sofar++]=c;
61           linebuffer[sofar]='\0';
62           break;
63         }
64       }
65     }
66     
67     if(linebuffer[0]=='#'){
68       sofar=0;
69     }else{
70       return(linebuffer);
71     }
72   }
73 }
74
75 void vqbook_unquantize(vqbook *b){
76   long j,k;
77   double mindel=float24_unpack(b->min);
78   double delta=float24_unpack(b->delta);
79   if(!b->valuelist)b->valuelist=malloc(sizeof(double)*b->entries*b->dim);
80   
81   for(j=0;j<b->entries;j++){
82     double last=0.;
83     for(k=0;k<b->dim;k++){
84       double val=b->quantlist[j*b->dim+k]*delta+last+mindel;
85       b->valuelist[j*b->dim+k]=val;
86       if(b->sequencep)last=val;
87
88     }
89   }
90 }
91
92
93 /* command line:
94    run outbase [-m] [-s <start>,<n>] datafile [-s <start>,<n>] [datafile...]
95
96    produces: outbase-residue.m (error between input data and chosen codewords;
97                                 can be used to cascade)
98              outbase-cells.m   (2d gnuplot file of cells if -m)
99
100    currently assumes a 'sequenced' codebook wants its test data to be
101    normalized to begin at zero... */
102
103 int main(int argc,char *argv[]){
104   vqbook *b=&CODEBOOK;
105   FILE *cells=NULL;
106   FILE *residue=NULL;
107   FILE *in=NULL;
108   char *line,*name;
109   long i,j,k;
110   int start=0,num=-1;
111
112   double mean=0.,meansquare=0.,mean_count=0.;
113   
114   argv++;
115
116   if(*argv==NULL){
117     fprintf(stderr,"Need a basename.\n");
118     exit(1);
119   }
120
121   name=strdup(*argv);
122   vqbook_unquantize(b);
123
124   {
125     char buf[80];
126     snprintf(buf,80,"%s-residue.vqd",name);
127     residue=fopen(buf,"w");
128     if(!residue){
129       fprintf(stderr,"Unable to open output file %s\n",buf);
130       exit(1);
131     }
132   }   
133
134   /* parse the command line; handle things as the come */
135   argv=argv++;
136   while(*argv){
137     if(argv[0][0]=='-'){
138       /* it's an option */
139       switch(argv[0][1]){
140       case 'm':
141         {
142           char buf[80];
143           snprintf(buf,80,"%s-cells.m",name);
144           cells=fopen(buf,"w");
145           if(!cells){
146             fprintf(stderr,"Unable to open output file %s\n",buf);
147             exit(1);
148           }
149         }   
150         argv++;
151         break;
152       case 's':
153         if(!argv[1]){
154           fprintf(stderr,"Option %s missing argument.\n",argv[0]);
155           exit(1);
156         }      
157         if(sscanf(argv[1],"%d,%d",&start,&num)!=2){
158           num= -1;
159           if(sscanf(argv[1],"%d",&start)!=1){
160             fprintf(stderr,"Option %s syntax error.\n",argv[0]);
161             exit(1);
162           }
163         }
164         argv+=2;
165         break;
166       }
167     }else{
168       /* it's an input file */
169       char *file=strdup(*argv++);
170       FILE *in;
171       int cols=-1;
172
173       in=fopen(file,"r");
174       if(in==NULL){
175         fprintf(stderr,"Could not open input file %s\n",file);
176         exit(1);
177       }
178
179       while((line=rline(in))){
180         if(cols==-1){
181           char *temp=line;
182           while(*temp==' ')temp++;
183           for(cols=0;*temp;cols++){
184             while(*temp>32)temp++;
185             while(*temp==' ')temp++;
186           }
187         }
188         {
189           int i;
190           double *p=malloc(cols*sizeof(double));
191           if(start*num+b->dim>cols){
192             fprintf(stderr,"ran out of columns reading %s\n",file);
193             exit(1);
194           }
195           while(*line==' ')line++;
196           for(i=0;i<cols;i++){
197
198             /* static length buffer bug workaround */
199             char *temp=line;
200             char old;
201             while(*temp>32)temp++;
202
203             old=temp[0];
204             temp[0]='\0';
205             p[i]=atof(line);
206             temp[0]=old;
207             
208             while(*line>32)line++;
209             while(*line==' ')line++;
210           }
211           if(num<=0)num=(cols-start)/b->dim;
212           for(i=num-1;i>=0;i--){
213             int entry;
214             double *base=p+start+i*b->dim;
215
216             /* if this is a sequenced book and i||start,
217                normalize the beginning to zero */
218             if(b->sequencep && (i>0 || start>0)){
219               for(k=0;k<b->dim;k++)
220                 base[k]-= *(base-1);
221             }
222
223             /* assign the point */
224             entry=vqenc_entry(b,base);
225
226             /* accumulate metrics */
227             for(k=0;k<b->dim;k++){
228               double err=base[k]-b->valuelist[k+entry*b->dim];
229               mean+=fabs(err);
230               meansquare+=err*err;
231               mean_count++;
232             }
233
234             /* brute force it... did that work better? */
235
236
237             /* paint the cell if -m */
238             if(cells){
239               fprintf(cells,"%g %g\n%g %g\n\n",
240                       base[0],base[1],
241                       b->valuelist[0+entry*b->dim],
242                       b->valuelist[1+entry*b->dim]);
243             }
244
245             /* write cascading data */
246
247
248
249           }
250           free(b);
251         }
252       }
253       fclose(in);
254     }
255   }
256   
257   
258   fclose(residue);
259   if(cells)fclose(cells);
260
261   /* print accumulated error statistics */
262   fprintf(stderr,"results:\n\tmean squared error:%g\n\tmean error:%g\n\n",
263           sqrt(meansquare/mean_count),mean/mean_count);
264
265   return 0;
266 }