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.15 2000/02/16 16:18:38 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_mindist,
132 vqext_metric,vqext_weight);
136 line=rline(in,out,1);
137 if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta,
138 &q.quant,&q.sequencep)!=4){
139 fprintf(stderr,"Syntax error reading book file\n");
143 /* quantized entries */
145 for(j=0;j<entries;j++){
147 line=rline(in,out,0);
148 sscanf(line,"%lf",&a);
152 vqgen_unquantize(&v,&q);
156 for(j=0;j<entries;j++){
157 line=rline(in,out,0);
158 sscanf(line,"%lf",&a);
163 double *b=alloca((dim+vqext_aux)*sizeof(double));
165 v.entries=0; /* hack to avoid reseeding */
167 for(k=0;k<dim+vqext_aux;k++){
168 line=rline(in,out,0);
170 sscanf(line,"%lf",b+k);
173 vqgen_addpoint(&v,b,b+dim);
182 /* get the rest... */
188 fprintf(stderr,"Option %s missing argument.\n",argv[0]);
193 if(sscanf(argv[1],"%d,%d,%d",&entries,&dim,&q.quant)!=3)
197 if(sscanf(argv[1],"%d,%d",&start,&num)!=2){
199 if(sscanf(argv[1],"%d",&start)!=1)
204 if(sscanf(argv[1],"%lf",&desired)!=1)
208 if(sscanf(argv[1],"%d",&iter)!=1)
212 fprintf(stderr,"Unknown option %s\n",argv[0]);
217 /* it's an input file */
218 char *file=strdup(*argv++);
223 if(dim==-1 || entries==-1 || q.quant==-1){
224 fprintf(stderr,"-p required when training a new set\n");
227 vqgen_init(&v,dim,vqext_aux,entries,vqext_mindist,
228 vqext_metric,vqext_weight);
234 fprintf(stderr,"Could not open input file %s\n",file);
237 fprintf(out,"# training file entry: %s\n",file);
239 while((line=rline(in,out,0))){
242 while(*temp==' ')temp++;
243 for(cols=0;*temp;cols++){
244 while(*temp>32)temp++;
245 while(*temp==' ')temp++;
251 if(start+num*dim>cols){
252 fprintf(stderr,"ran out of columns reading %s\n",file);
255 while(*line==' ')line++;
258 /* static length buffer bug workaround */
261 while(*temp>32)temp++;
268 while(*line>32)line++;
269 while(*line==' ')line++;
271 if(num<=0)num=(cols-start)/dim;
273 vqext_addpoint_adj(&v,b,start+i*dim,dim,cols);
282 fprintf(stderr,"No input files!\n");
286 vqext_preprocess(&v);
289 signal(SIGTERM,setexit);
290 signal(SIGINT,setexit);
292 for(i=0;i<iter && !exiting;i++){
295 vqgen_unquantize(&v,&q);
296 vqgen_cellmetric(&v);
298 result=vqgen_iterate(&v);
299 vqext_quantize(&v,&q);
300 if(result<desired)break;
305 fprintf(out,"# OggVorbis VQ codebook trainer, intermediate file\n");
306 fprintf(out,"%s\n",vqext_booktype);
307 fprintf(out,"%d %d %d\n",entries,dim,vqext_aux);
308 fprintf(out,"%ld %ld %d %d\n",q.min,q.delta,q.quant,q.sequencep);
310 /* quantized entries */
311 fprintf(out,"# quantized entries---\n");
313 for(j=0;j<entries;j++)
315 fprintf(out,"%d\n",(int)(rint(v.entrylist[i++])));
317 fprintf(out,"# biases---\n");
319 for(j=0;j<entries;j++)
320 fprintf(out,"%f\n",v.bias[i++]);
322 fprintf(out,"# points---\n");
324 for(j=0;j<v.points;j++)
325 for(k=0;k<dim+vqext_aux;k++)
326 fprintf(out,"%f\n",v.pointlist[i++]);
330 vqgen_unquantize(&v,&q);
331 vqgen_cellmetric(&v);
335 fprintf(stderr,"Syntax error in argument '%s'\n",*argv);