/* assume vqext_aux==1 */ void vqext_addpoint_adj(vqgen *v,float *b,int start,int dim,int cols,int num){ float *a=alloca(sizeof(float)*(dim+1)); /* +aux */ float base=0; int i; for(i=0;i<dim;i++) base=a[i]=b[i+start]+base; if(start+dim+1>cols) /* +aux */ a[i]=M_PI; else a[i]=b[i+start]+base; vqgen_addpoint(v,a,a+dim); }
int main(int argc,char *argv[]){ vqgen v; static_codebook c; codebook b; quant_meta q; long *quantlist=NULL; int entries=-1,dim=-1,aux=-1; FILE *out=NULL; FILE *in=NULL; char *line,*name; long i,j,k; b.c=&c; if(argv[1]==NULL){ fprintf(stderr,"Need a trained data set on the command line.\n"); exit(1); } { char *ptr; char *filename=strdup(argv[1]); in=fopen(filename,"r"); if(!in){ fprintf(stderr,"Could not open input file %s\n",filename); exit(1); } ptr=strrchr(filename,'-'); if(ptr){ *ptr='\0'; name=strdup(filename); sprintf(ptr,".vqh"); }else{ name=strdup(filename); strcat(filename,".vqh"); } out=fopen(filename,"w"); if(out==NULL){ fprintf(stderr,"Unable to open %s for writing\n",filename); exit(1); } } /* suck in the trained book */ /* read book type, but it doesn't matter */ line=rline(in,out); line=rline(in,out); if(sscanf(line,"%d %d %d",&entries,&dim,&aux)!=3){ fprintf(stderr,"Syntax error reading book file\n"); exit(1); } /* just use it to allocate mem */ vqgen_init(&v,dim,0,entries,0.f,NULL,NULL,0); /* quant */ line=rline(in,out); if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta, &q.quant,&q.sequencep)!=4){ fprintf(stderr,"Syntax error reading book file\n"); exit(1); } /* quantized entries */ /* save quant data; we don't want to requantize later as our method is currently imperfect wrt repeated application */ i=0; quantlist=_ogg_malloc(sizeof(long)*v.elements*v.entries); for(j=0;j<entries;j++){ float a; for(k=0;k<dim;k++){ line=rline(in,out); sscanf(line,"%f",&a); v.entrylist[i]=a; quantlist[i++]=rint(a); } } /* ignore bias */ for(j=0;j<entries;j++)line=rline(in,out); free(v.bias); v.bias=NULL; /* training points */ { float *b=alloca(sizeof(float)*(dim+aux)); i=0; v.entries=0; /* hack to avoid reseeding */ while(1){ for(k=0;k<dim+aux;k++){ line=rline(in,out); if(!line)break; sscanf(line,"%f",b+k); } if(feof(in))break; vqgen_addpoint(&v,b,NULL); } v.entries=entries; } fclose(in); vqgen_unquantize(&v,&q); /* build the book */ vqsp_book(&v,&b,quantlist); c.q_min=q.min; c.q_delta=q.delta; c.q_quant=q.quant; c.q_sequencep=q.sequencep; /* save the book in C header form */ write_codebook(out,name,b.c); fclose(out); exit(0); }
void vqext_addpoint_adj(vqgen *v,float *b,int start,int dim,int cols,int num){ vqgen_addpoint(v,b+start,NULL); }
int main(int argc,char *argv[]){ vqgen v; int entries=-1,dim=-1; int start=0,num=-1; float desired=.05f,mindist=0.f; int iter=1000; int biasp=1; int centroid=0; FILE *out=NULL; char *line; long i,j,k; int init=0; q.quant=-1; argv++; if(!*argv){ usage(); exit(0); } /* get the book name, a preexisting book to continue training */ { FILE *in=NULL; char *filename=alloca(strlen(*argv)+30),*ptr; strcpy(filename,*argv); in=fopen(filename,"r"); ptr=strrchr(filename,'-'); if(ptr){ int num; ptr++; num=atoi(ptr); sprintf(ptr,"%d.vqi",num+1); }else strcat(filename,"-0.vqi"); out=fopen(filename,"w"); if(out==NULL){ fprintf(stderr,"Unable to open %s for writing\n",filename); exit(1); } if(in){ /* we wish to suck in a preexisting book and continue to train it */ float a; line=rline(in,out,1); if(strcmp(line,vqext_booktype)){ fprintf(stderr,"wrong book type; %s!=%s\n",line,vqext_booktype); exit(1); } line=rline(in,out,1); if(sscanf(line,"%d %d %d",&entries,&dim,&vqext_aux)!=3){ fprintf(stderr,"Syntax error reading book file\n"); exit(1); } vqgen_init(&v,dim,vqext_aux,entries,mindist, vqext_metric,vqext_weight,centroid); init=1; /* quant setup */ line=rline(in,out,1); if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta, &q.quant,&q.sequencep)!=4){ fprintf(stderr,"Syntax error reading book file\n"); exit(1); } /* quantized entries */ i=0; for(j=0;j<entries;j++){ for(k=0;k<dim;k++){ line=rline(in,out,0); sscanf(line,"%f",&a); v.entrylist[i++]=a; } } vqgen_unquantize(&v,&q); /* bias */ i=0; for(j=0;j<entries;j++){ line=rline(in,out,0); sscanf(line,"%f",&a); v.bias[i++]=a; } v.seeded=1; { float *b=alloca((dim+vqext_aux)*sizeof(float)); i=0; while(1){ for(k=0;k<dim+vqext_aux;k++){ line=rline(in,out,0); if(!line)break; sscanf(line,"%f",b+k); } if(feof(in))break; vqgen_addpoint(&v,b,b+dim); } } fclose(in); } } /* get the rest... */ argv=argv++; while(*argv){ if(argv[0][0]=='-'){ /* it's an option */ if(!argv[1]){ fprintf(stderr,"Option %s missing argument.\n",argv[0]); exit(1); } switch(argv[0][1]){ case 'p': if(sscanf(argv[1],"%d,%d,%d",&entries,&dim,&q.quant)!=3) goto syner; break; case 's': if(sscanf(argv[1],"%d,%d",&start,&num)!=2){ num= -1; if(sscanf(argv[1],"%d",&start)!=1) goto syner; } break; case 'e': if(sscanf(argv[1],"%f",&desired)!=1) goto syner; break; case 'd': if(sscanf(argv[1],"%f",&mindist)!=1) goto syner; if(init)v.mindist=mindist; break; case 'i': if(sscanf(argv[1],"%d",&iter)!=1) goto syner; break; case 'b': biasp=0; break; case 'c': centroid=1; break; default: fprintf(stderr,"Unknown option %s\n",argv[0]); exit(1); } argv+=2; }else{ /* it's an input file */ char *file=strdup(*argv++); FILE *in; int cols=-1; if(!init){ if(dim==-1 || entries==-1 || q.quant==-1){ fprintf(stderr,"-p required when training a new set\n"); exit(1); } vqgen_init(&v,dim,vqext_aux,entries,mindist, vqext_metric,vqext_weight,centroid); init=1; } in=fopen(file,"r"); if(in==NULL){ fprintf(stderr,"Could not open input file %s\n",file); exit(1); } fprintf(out,"# training file entry: %s\n",file); while((line=rline(in,out,0))){ if(cols==-1){ char *temp=line; while(*temp==' ')temp++; for(cols=0;*temp;cols++){ while(*temp>32)temp++; while(*temp==' ')temp++; } fprintf(stderr,"%d colums per line in file %s\n",cols,file); } { int i; float b[cols]; if(start+num*dim>cols){ fprintf(stderr,"ran out of columns reading %s\n",file); exit(1); } while(*line==' ')line++; for(i=0;i<cols;i++){ /* static length buffer bug workaround */ char *temp=line; char old; while(*temp>32)temp++; old=temp[0]; temp[0]='\0'; b[i]=atof(line); temp[0]=old; while(*line>32)line++; while(*line==' ')line++; } if(num<=0)num=(cols-start)/dim; for(i=0;i<num;i++) vqext_addpoint_adj(&v,b,start+i*dim,dim,cols,num); } } fclose(in); } } if(!init){ fprintf(stderr,"No input files!\n"); exit(1); } vqext_preprocess(&v); /* train the book */ signal(SIGTERM,setexit); signal(SIGINT,setexit); for(i=0;i<iter && !exiting;i++){ float result; if(i!=0){ vqgen_unquantize(&v,&q); vqgen_cellmetric(&v); } result=vqgen_iterate(&v,biasp); vqext_quantize(&v,&q); if(result<desired)break; } /* save the book */ fprintf(out,"# OggVorbis VQ codebook trainer, intermediate file\n"); fprintf(out,"%s\n",vqext_booktype); fprintf(out,"%d %d %d\n",entries,dim,vqext_aux); fprintf(out,"%ld %ld %d %d\n", q.min,q.delta,q.quant,q.sequencep); /* quantized entries */ fprintf(out,"# quantized entries---\n"); i=0; for(j=0;j<entries;j++) for(k=0;k<dim;k++) fprintf(out,"%d\n",(int)(rint(v.entrylist[i++]))); fprintf(out,"# biases---\n"); i=0; for(j=0;j<entries;j++) fprintf(out,"%f\n",v.bias[i++]); /* we may have done the density limiting mesh trick; refetch the training points from the temp file */ rewind(v.asciipoints); fprintf(out,"# points---\n"); { /* sloppy, no error handling */ long bytes; char buff[4096]; while((bytes=fread(buff,1,4096,v.asciipoints))) while(bytes)bytes-=fwrite(buff,1,bytes,out); } fclose(out); fclose(v.asciipoints); vqgen_unquantize(&v,&q); vqgen_cellmetric(&v); exit(0); syner: fprintf(stderr,"Syntax error in argument '%s'\n",*argv); exit(1); }