Updates to Tomato RAF including NGINX && PHP
[tomato.git] / release / src / router / libvorbis / vq / train.c
bloba76a9a32bc4419a1e5e0eb18122bd0236104abaa
1 /********************************************************************
2 * *
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. *
7 * *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function: utility main for training codebooks
14 last mod: $Id: train.c 16037 2009-05-26 21:10:58Z xiphmont $
16 ********************************************************************/
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <math.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <signal.h>
24 #include "vqgen.h"
25 #include "vqext.h"
26 #include "bookutil.h"
28 static char *rline(FILE *in,FILE *out,int pass){
29 while(1){
30 char *line=get_line(in);
31 if(line && line[0]=='#'){
32 if(pass)fprintf(out,"%s\n",line);
33 }else{
34 return(line);
39 /* command line:
40 trainvq vqfile [options] trainfile [trainfile]
42 options: -params entries,dim,quant
43 -subvector start[,num]
44 -error desired_error
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"
59 "examples:\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);
70 int exiting=0;
71 void setexit(int dummy){
72 fprintf(stderr,"\nexiting... please wait to finish this iteration\n");
73 exiting=1;
76 int main(int argc,char *argv[]){
77 vqgen v;
79 int entries=-1,dim=-1;
80 int start=0,num=-1;
81 float desired=.05f,mindist=0.f;
82 int iter=1000;
83 int biasp=1;
84 int centroid=0;
86 FILE *out=NULL;
87 char *line;
88 long i,j,k;
89 int init=0;
90 q.quant=-1;
92 argv++;
93 if(!*argv){
94 usage();
95 exit(0);
98 /* get the book name, a preexisting book to continue training */
100 FILE *in=NULL;
101 char *filename=alloca(strlen(*argv)+30),*ptr;
103 strcpy(filename,*argv);
104 in=fopen(filename,"r");
105 ptr=strrchr(filename,'-');
106 if(ptr){
107 int num;
108 ptr++;
109 num=atoi(ptr);
110 sprintf(ptr,"%d.vqi",num+1);
111 }else
112 strcat(filename,"-0.vqi");
114 out=fopen(filename,"w");
115 if(out==NULL){
116 fprintf(stderr,"Unable to open %s for writing\n",filename);
117 exit(1);
120 if(in){
121 /* we wish to suck in a preexisting book and continue to train it */
122 float a;
124 line=rline(in,out,1);
125 if(strcmp(line,vqext_booktype)){
126 fprintf(stderr,"wrong book type; %s!=%s\n",line,vqext_booktype);
127 exit(1);
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");
133 exit(1);
136 vqgen_init(&v,dim,vqext_aux,entries,mindist,
137 vqext_metric,vqext_weight,centroid);
138 init=1;
140 /* quant setup */
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");
145 exit(1);
148 /* quantized entries */
149 i=0;
150 for(j=0;j<entries;j++){
151 for(k=0;k<dim;k++){
152 line=rline(in,out,0);
153 sscanf(line,"%f",&a);
154 v.entrylist[i++]=a;
157 vqgen_unquantize(&v,&q);
159 /* bias */
160 i=0;
161 for(j=0;j<entries;j++){
162 line=rline(in,out,0);
163 sscanf(line,"%f",&a);
164 v.bias[i++]=a;
167 v.seeded=1;
169 float *b=alloca((dim+vqext_aux)*sizeof(float));
170 i=0;
171 while(1){
172 for(k=0;k<dim+vqext_aux;k++){
173 line=rline(in,out,0);
174 if(!line)break;
175 sscanf(line,"%f",b+k);
177 if(feof(in))break;
178 vqgen_addpoint(&v,b,b+dim);
182 fclose(in);
186 /* get the rest... */
187 argv=argv++;
188 while(*argv){
189 if(argv[0][0]=='-'){
190 /* it's an option */
191 if(!argv[1]){
192 fprintf(stderr,"Option %s missing argument.\n",argv[0]);
193 exit(1);
195 switch(argv[0][1]){
196 case 'p':
197 if(sscanf(argv[1],"%d,%d,%d",&entries,&dim,&q.quant)!=3)
198 goto syner;
199 break;
200 case 's':
201 if(sscanf(argv[1],"%d,%d",&start,&num)!=2){
202 num= -1;
203 if(sscanf(argv[1],"%d",&start)!=1)
204 goto syner;
206 break;
207 case 'e':
208 if(sscanf(argv[1],"%f",&desired)!=1)
209 goto syner;
210 break;
211 case 'd':
212 if(sscanf(argv[1],"%f",&mindist)!=1)
213 goto syner;
214 if(init)v.mindist=mindist;
215 break;
216 case 'i':
217 if(sscanf(argv[1],"%d",&iter)!=1)
218 goto syner;
219 break;
220 case 'b':
221 biasp=0;
222 break;
223 case 'c':
224 centroid=1;
225 break;
226 default:
227 fprintf(stderr,"Unknown option %s\n",argv[0]);
228 exit(1);
230 argv+=2;
231 }else{
232 /* it's an input file */
233 char *file=strdup(*argv++);
234 FILE *in;
235 int cols=-1;
237 if(!init){
238 if(dim==-1 || entries==-1 || q.quant==-1){
239 fprintf(stderr,"-p required when training a new set\n");
240 exit(1);
242 vqgen_init(&v,dim,vqext_aux,entries,mindist,
243 vqext_metric,vqext_weight,centroid);
244 init=1;
247 in=fopen(file,"r");
248 if(in==NULL){
249 fprintf(stderr,"Could not open input file %s\n",file);
250 exit(1);
252 fprintf(out,"# training file entry: %s\n",file);
254 while((line=rline(in,out,0))){
255 if(cols==-1){
256 char *temp=line;
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);
267 int i;
268 float b[cols];
269 if(start+num*dim>cols){
270 fprintf(stderr,"ran out of columns reading %s\n",file);
271 exit(1);
273 while(*line==' ')line++;
274 for(i=0;i<cols;i++){
276 /* static length buffer bug workaround */
277 char *temp=line;
278 char old;
279 while(*temp>32)temp++;
281 old=temp[0];
282 temp[0]='\0';
283 b[i]=atof(line);
284 temp[0]=old;
286 while(*line>32)line++;
287 while(*line==' ')line++;
289 if(num<=0)num=(cols-start)/dim;
290 for(i=0;i<num;i++)
291 vqext_addpoint_adj(&v,b,start+i*dim,dim,cols,num);
295 fclose(in);
299 if(!init){
300 fprintf(stderr,"No input files!\n");
301 exit(1);
304 vqext_preprocess(&v);
306 /* train the book */
307 signal(SIGTERM,setexit);
308 signal(SIGINT,setexit);
310 for(i=0;i<iter && !exiting;i++){
311 float result;
312 if(i!=0){
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;
321 /* save the book */
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");
331 i=0;
332 for(j=0;j<entries;j++)
333 for(k=0;k<dim;k++)
334 fprintf(out,"%d\n",(int)(rint(v.entrylist[i++])));
336 fprintf(out,"# biases---\n");
337 i=0;
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 */
348 long bytes;
349 char buff[4096];
350 while((bytes=fread(buff,1,4096,v.asciipoints)))
351 while(bytes)bytes-=fwrite(buff,1,bytes,out);
354 fclose(out);
355 fclose(v.asciipoints);
357 vqgen_unquantize(&v,&q);
358 vqgen_cellmetric(&v);
359 exit(0);
361 syner:
362 fprintf(stderr,"Syntax error in argument '%s'\n",*argv);
363 exit(1);