Incremental update, seperated weighting from the metric
[platform/upstream/libvorbis.git] / vq / build.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-1999             *
9  * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company       *
10  * http://www.xiph.org/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: utility main for building codebooks from training sets
15  author: Monty <xiphmont@mit.edu>
16  modifications by: Monty
17  last modification date: Dec 15 1999
18
19  ********************************************************************/
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include <string.h>
25 #include <errno.h>
26 #include "vqgen.h"
27
28 static char *linebuffer=NULL;
29 static int  lbufsize=0;
30 static char *rline(FILE *in,FILE *out,int pass){
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       if(pass)fprintf(out,"%s\n",linebuffer);
64       sofar=0;
65     }else{
66       return(linebuffer);
67     }
68   }
69 }
70
71 /* command line:
72    buildvq file
73 */
74
75 int main(int argc,char *argv[]){
76   vqgen v;
77   vqbook b;
78   quant_meta q;
79   int *quantlist=NULL;
80
81   int entries=-1,dim=-1,dummy;
82   FILE *out=NULL;
83   FILE *in=NULL;
84   char *line,*name;
85   long i,j,k;
86
87   if(argv[1]==NULL){
88     fprintf(stderr,"Need a trained data set on the command line.\n");
89     exit(1);
90   }
91
92   {
93     char *ptr;
94     char *filename=strdup(argv[1]);
95
96     in=fopen(filename,"r");
97     if(!in){
98       fprintf(stderr,"Could not open input file %s\n",filename);
99       exit(1);
100     }
101     
102     ptr=strrchr(filename,'.');
103     if(ptr){
104       *ptr='\0';
105       name=strdup(ptr);
106       sprintf(ptr,".h");
107     }else{
108       name=strdup(filename);
109       strcat(filename,".h");
110     }
111
112     out=fopen(filename,"w");
113     if(out==NULL){
114       fprintf(stderr,"Unable to open %s for writing\n",filename);
115       exit(1);
116     }
117   }
118
119   /* suck in the trained book */
120
121   /* read book type, but it doesn't matter */
122   line=rline(in,out,1);
123   
124   line=rline(in,out,1);
125   if(sscanf(line,"%d %d %d",&entries,&dim,&dummy)!=2){
126     fprintf(stderr,"Syntax error reading book file\n");
127     exit(1);
128   }
129   
130   /* just use it to allocate mem */
131   vqgen_init(&v,dim,0,entries,NULL,NULL);
132   
133   /* quant */
134   line=rline(in,out,1);
135   if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta,
136             &q.quant,&q.sequencep)!=4){
137     fprintf(stderr,"Syntax error reading book file\n");
138     exit(1);
139   }
140   
141   /* quantized entries */
142   /* save quant data; we don't want to requantize later as our method
143      is currently imperfect wrt repeated application */
144   i=0;
145   quantlist=malloc(sizeof(int)*v.elements*v.entries);
146   for(j=0;j<entries;j++){
147     double a;
148     for(k=0;k<dim;k++){
149       line=rline(in,out,0);
150       sscanf(line,"%lf",&a);
151       v.entrylist[i]=a;
152       quantlist[i++]=rint(a);
153     }
154   }    
155   
156   /* ignore bias */
157   for(j=0;j<entries;j++)line=rline(in,out,0);
158   free(v.bias);
159   v.bias=NULL;
160   
161   /* training points */
162   {
163     double b[80];
164     i=0;
165     v.entries=0; /* hack to avoid reseeding */
166     while(1){
167       for(k=0;k<dim && k<80;k++){
168         line=rline(in,out,0);
169         if(!line)break;
170         sscanf(line,"%lf",b+k);
171       }
172       if(feof(in))break;
173       vqgen_addpoint(&v,b,NULL);
174     }
175     v.entries=entries;
176   }
177   
178   fclose(in);
179   vqgen_unquantize(&v,&q);
180
181   /* build the book */
182   vqsp_book(&v,&b);
183
184   /* save the book in C header form */
185
186
187
188
189   exit(0);
190 }