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