1 /********************************************************************
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. *
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/ *
12 ********************************************************************
14 function: utility main for training codebooks
15 last mod: $Id: train.c,v 1.14 2000/01/10 10:42:06 xiphmont Exp $
17 ********************************************************************/
29 static char *rline(FILE *in,FILE *out,int pass){
31 char *line=get_line(in);
32 if(line && line[0]=='#'){
33 if(pass)fprintf(out,"%s\n",line);
41 trainvq vqfile [options] trainfile [trainfile]
43 options: -params entries,dim,quant
44 -subvector start[,num]
46 -iterations iterations
49 static void usage(void){
50 fprintf(stderr, "\nOggVorbis %s VQ codebook trainer\n\n"
51 "<foo>vqtrain vqfile [options] [datasetfile] [datasetfile]\n"
52 "options: -p[arams] <entries,dim,quant>\n"
53 " -s[ubvector] <start[,num]>\n"
54 " -e[rror] <desired_error>\n"
55 " -i[terations] <maxiterations>\n\n"
57 " train a new codebook to 1%% tolerance on datafile 'foo':\n"
58 " xxxvqtrain book -p 256,6,8 -e .01 foo\n"
59 " (produces a trained set in book-0.vqi)\n\n"
60 " continue training 'book-0.vqi' (produces book-1.vqi):\n"
61 " xxxvqtrain book-0.vqi\n\n"
62 " add subvector from element 1 to <dimension> from files\n"
63 " data*.m to the training in progress, prodicing book-1.vqi:\n"
64 " xxxvqtrain book-0.vqi -s 1,1 data*.m\n\n",vqext_booktype);
68 void setexit(int dummy){
69 fprintf(stderr,"\nexiting... please wait to finish this iteration\n");
73 int main(int argc,char *argv[]){
76 int entries=-1,dim=-1;
93 /* get the book name, a preexisting book to continue training */
96 char *filename=alloca(strlen(*argv)+30),*ptr;
98 strcpy(filename,*argv);
99 in=fopen(filename,"r");
100 ptr=strrchr(filename,'-');
105 sprintf(ptr,"%d.vqi",num+1);
107 strcat(filename,"-0.vqi");
109 out=fopen(filename,"w");
111 fprintf(stderr,"Unable to open %s for writing\n",filename);
116 /* we wish to suck in a preexisting book and continue to train it */
119 line=rline(in,out,1);
120 if(strcmp(line,vqext_booktype)){
121 fprintf(stderr,"wrong book type; %s!=%s\n",line,vqext_booktype);
125 line=rline(in,out,1);
126 if(sscanf(line,"%d %d %d",&entries,&dim,&vqext_aux)!=3){
127 fprintf(stderr,"Syntax error reading book file\n");
131 vqgen_init(&v,dim,vqext_aux,entries,vqext_metric,vqext_weight);
135 line=rline(in,out,1);
136 if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta,
137 &q.quant,&q.sequencep)!=4){
138 fprintf(stderr,"Syntax error reading book file\n");
142 /* quantized entries */
144 for(j=0;j<entries;j++){
146 line=rline(in,out,0);
147 sscanf(line,"%lf",&a);
151 vqgen_unquantize(&v,&q);
155 for(j=0;j<entries;j++){
156 line=rline(in,out,0);
157 sscanf(line,"%lf",&a);
162 double *b=alloca((dim+vqext_aux)*sizeof(double));
164 v.entries=0; /* hack to avoid reseeding */
166 for(k=0;k<dim+vqext_aux;k++){
167 line=rline(in,out,0);
169 sscanf(line,"%lf",b+k);
172 vqgen_addpoint(&v,b,b+dim);
181 /* get the rest... */
187 fprintf(stderr,"Option %s missing argument.\n",argv[0]);
192 if(sscanf(argv[1],"%d,%d,%d",&entries,&dim,&q.quant)!=3)
196 if(sscanf(argv[1],"%d,%d",&start,&num)!=2){
198 if(sscanf(argv[1],"%d",&start)!=1)
203 if(sscanf(argv[1],"%lf",&desired)!=1)
207 if(sscanf(argv[1],"%d",&iter)!=1)
211 fprintf(stderr,"Unknown option %s\n",argv[0]);
216 /* it's an input file */
217 char *file=strdup(*argv++);
222 if(dim==-1 || entries==-1 || q.quant==-1){
223 fprintf(stderr,"-p required when training a new set\n");
226 vqgen_init(&v,dim,vqext_aux,entries,vqext_metric,vqext_weight);
232 fprintf(stderr,"Could not open input file %s\n",file);
235 fprintf(out,"# training file entry: %s\n",file);
237 while((line=rline(in,out,0))){
240 while(*temp==' ')temp++;
241 for(cols=0;*temp;cols++){
242 while(*temp>32)temp++;
243 while(*temp==' ')temp++;
249 if(start+num*dim>cols){
250 fprintf(stderr,"ran out of columns reading %s\n",file);
253 while(*line==' ')line++;
256 /* static length buffer bug workaround */
259 while(*temp>32)temp++;
266 while(*line>32)line++;
267 while(*line==' ')line++;
269 if(num<=0)num=(cols-start)/dim;
271 vqext_addpoint_adj(&v,b,start+i*dim,dim,cols);
280 fprintf(stderr,"No input files!\n");
284 vqext_preprocess(&v);
287 signal(SIGTERM,setexit);
288 signal(SIGINT,setexit);
290 for(i=0;i<iter && !exiting;i++){
292 if(i!=0)vqgen_unquantize(&v,&q);
293 result=vqgen_iterate(&v);
294 vqgen_quantize(&v,&q);
295 if(result<desired)break;
300 fprintf(out,"# OggVorbis VQ codebook trainer, intermediate file\n");
301 fprintf(out,"%s\n",vqext_booktype);
302 fprintf(out,"%d %d %d\n",entries,dim,vqext_aux);
303 fprintf(out,"%ld %ld %d %d\n",q.min,q.delta,q.quant,q.sequencep);
305 /* quantized entries */
306 fprintf(out,"# quantized entries---\n");
308 for(j=0;j<entries;j++)
310 fprintf(out,"%d\n",(int)(rint(v.entrylist[i++])));
312 fprintf(out,"# biases---\n");
314 for(j=0;j<entries;j++)
315 fprintf(out,"%f\n",v.bias[i++]);
317 fprintf(out,"# points---\n");
319 for(j=0;j<v.points;j++)
320 for(k=0;k<dim+vqext_aux;k++)
321 fprintf(out,"%f\n",v.pointlist[i++]);
327 fprintf(stderr,"Syntax error in argument '%s'\n",*argv);