1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: utility main for training codebooks
14 last mod: $Id: train.c 16037 2009-05-26 21:10:58Z xiphmont $
16 ********************************************************************/
28 static char *rline(FILE *in
,FILE *out
,int pass
){
30 char *line
=get_line(in
);
31 if(line
&& line
[0]=='#'){
32 if(pass
)fprintf(out
,"%s\n",line
);
40 trainvq vqfile [options] trainfile [trainfile]
42 options: -params entries,dim,quant
43 -subvector start[,num]
45 -iterations iterations
48 static void usage(void){
49 fprintf(stderr
, "\nOggVorbis %s VQ codebook trainer\n\n"
50 "<foo>vqtrain vqfile [options] [datasetfile] [datasetfile]\n"
51 "options: -p[arams] <entries,dim,quant>\n"
52 " -s[ubvector] <start[,num]>\n"
53 " -e[rror] <desired_error>\n"
54 " -i[terations] <maxiterations>\n"
55 " -d[istance] quantization mesh spacing for density limitation\n"
56 " -b <dummy> eliminate cell size biasing; use normal LBG\n\n"
57 " -c <dummy> Use centroid (not median) midpoints\n"
60 " train a new codebook to 1%% tolerance on datafile 'foo':\n"
61 " xxxvqtrain book -p 256,6,8 -e .01 foo\n"
62 " (produces a trained set in book-0.vqi)\n\n"
63 " continue training 'book-0.vqi' (produces book-1.vqi):\n"
64 " xxxvqtrain book-0.vqi\n\n"
65 " add subvector from element 1 to <dimension> from files\n"
66 " data*.m to the training in progress, prodicing book-1.vqi:\n"
67 " xxxvqtrain book-0.vqi -s 1,1 data*.m\n\n",vqext_booktype
);
71 void setexit(int dummy
){
72 fprintf(stderr
,"\nexiting... please wait to finish this iteration\n");
76 int main(int argc
,char *argv
[]){
79 int entries
=-1,dim
=-1;
81 float desired
=.05f
,mindist
=0.f
;
98 /* get the book name, a preexisting book to continue training */
101 char *filename
=alloca(strlen(*argv
)+30),*ptr
;
103 strcpy(filename
,*argv
);
104 in
=fopen(filename
,"r");
105 ptr
=strrchr(filename
,'-');
110 sprintf(ptr
,"%d.vqi",num
+1);
112 strcat(filename
,"-0.vqi");
114 out
=fopen(filename
,"w");
116 fprintf(stderr
,"Unable to open %s for writing\n",filename
);
121 /* we wish to suck in a preexisting book and continue to train it */
124 line
=rline(in
,out
,1);
125 if(strcmp(line
,vqext_booktype
)){
126 fprintf(stderr
,"wrong book type; %s!=%s\n",line
,vqext_booktype
);
130 line
=rline(in
,out
,1);
131 if(sscanf(line
,"%d %d %d",&entries
,&dim
,&vqext_aux
)!=3){
132 fprintf(stderr
,"Syntax error reading book file\n");
136 vqgen_init(&v
,dim
,vqext_aux
,entries
,mindist
,
137 vqext_metric
,vqext_weight
,centroid
);
141 line
=rline(in
,out
,1);
142 if(sscanf(line
,"%ld %ld %d %d",&q
.min
,&q
.delta
,
143 &q
.quant
,&q
.sequencep
)!=4){
144 fprintf(stderr
,"Syntax error reading book file\n");
148 /* quantized entries */
150 for(j
=0;j
<entries
;j
++){
152 line
=rline(in
,out
,0);
153 sscanf(line
,"%f",&a
);
157 vqgen_unquantize(&v
,&q
);
161 for(j
=0;j
<entries
;j
++){
162 line
=rline(in
,out
,0);
163 sscanf(line
,"%f",&a
);
169 float *b
=alloca((dim
+vqext_aux
)*sizeof(float));
172 for(k
=0;k
<dim
+vqext_aux
;k
++){
173 line
=rline(in
,out
,0);
175 sscanf(line
,"%f",b
+k
);
178 vqgen_addpoint(&v
,b
,b
+dim
);
186 /* get the rest... */
192 fprintf(stderr
,"Option %s missing argument.\n",argv
[0]);
197 if(sscanf(argv
[1],"%d,%d,%d",&entries
,&dim
,&q
.quant
)!=3)
201 if(sscanf(argv
[1],"%d,%d",&start
,&num
)!=2){
203 if(sscanf(argv
[1],"%d",&start
)!=1)
208 if(sscanf(argv
[1],"%f",&desired
)!=1)
212 if(sscanf(argv
[1],"%f",&mindist
)!=1)
214 if(init
)v
.mindist
=mindist
;
217 if(sscanf(argv
[1],"%d",&iter
)!=1)
227 fprintf(stderr
,"Unknown option %s\n",argv
[0]);
232 /* it's an input file */
233 char *file
=strdup(*argv
++);
238 if(dim
==-1 || entries
==-1 || q
.quant
==-1){
239 fprintf(stderr
,"-p required when training a new set\n");
242 vqgen_init(&v
,dim
,vqext_aux
,entries
,mindist
,
243 vqext_metric
,vqext_weight
,centroid
);
249 fprintf(stderr
,"Could not open input file %s\n",file
);
252 fprintf(out
,"# training file entry: %s\n",file
);
254 while((line
=rline(in
,out
,0))){
257 while(*temp
==' ')temp
++;
258 for(cols
=0;*temp
;cols
++){
259 while(*temp
>32)temp
++;
260 while(*temp
==' ')temp
++;
263 fprintf(stderr
,"%d colums per line in file %s\n",cols
,file
);
269 if(start
+num
*dim
>cols
){
270 fprintf(stderr
,"ran out of columns reading %s\n",file
);
273 while(*line
==' ')line
++;
276 /* static length buffer bug workaround */
279 while(*temp
>32)temp
++;
286 while(*line
>32)line
++;
287 while(*line
==' ')line
++;
289 if(num
<=0)num
=(cols
-start
)/dim
;
291 vqext_addpoint_adj(&v
,b
,start
+i
*dim
,dim
,cols
,num
);
300 fprintf(stderr
,"No input files!\n");
304 vqext_preprocess(&v
);
307 signal(SIGTERM
,setexit
);
308 signal(SIGINT
,setexit
);
310 for(i
=0;i
<iter
&& !exiting
;i
++){
313 vqgen_unquantize(&v
,&q
);
314 vqgen_cellmetric(&v
);
316 result
=vqgen_iterate(&v
,biasp
);
317 vqext_quantize(&v
,&q
);
318 if(result
<desired
)break;
323 fprintf(out
,"# OggVorbis VQ codebook trainer, intermediate file\n");
324 fprintf(out
,"%s\n",vqext_booktype
);
325 fprintf(out
,"%d %d %d\n",entries
,dim
,vqext_aux
);
326 fprintf(out
,"%ld %ld %d %d\n",
327 q
.min
,q
.delta
,q
.quant
,q
.sequencep
);
329 /* quantized entries */
330 fprintf(out
,"# quantized entries---\n");
332 for(j
=0;j
<entries
;j
++)
334 fprintf(out
,"%d\n",(int)(rint(v
.entrylist
[i
++])));
336 fprintf(out
,"# biases---\n");
338 for(j
=0;j
<entries
;j
++)
339 fprintf(out
,"%f\n",v
.bias
[i
++]);
341 /* we may have done the density limiting mesh trick; refetch the
342 training points from the temp file */
344 rewind(v
.asciipoints
);
345 fprintf(out
,"# points---\n");
347 /* sloppy, no error handling */
350 while((bytes
=fread(buff
,1,4096,v
.asciipoints
)))
351 while(bytes
)bytes
-=fwrite(buff
,1,bytes
,out
);
355 fclose(v
.asciipoints
);
357 vqgen_unquantize(&v
,&q
);
358 vqgen_cellmetric(&v
);
362 fprintf(stderr
,"Syntax error in argument '%s'\n",*argv
);