From b53a6498079c7c5e89d8afbaad0f56ba78262c9a Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 15 Dec 1999 08:37:22 +0000 Subject: [PATCH] split out the include add quantization to training svn path=/trunk/vorbis/; revision=194 --- vq/train.c | 21 ++++++++++------- vq/vqgen.c | 80 +++++++++++++++++++++++--------------------------------------- vq/vqgen.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 60 deletions(-) create mode 100644 vq/vqgen.h diff --git a/vq/train.c b/vq/train.c index 446c6d5..4c0eddf 100644 --- a/vq/train.c +++ b/vq/train.c @@ -14,7 +14,7 @@ function: utility main for training codebooks author: Monty modifications by: Monty - last modification date: Dec 10 1999 + last modification date: Dec 14 1999 ********************************************************************/ @@ -75,7 +75,7 @@ static int rline(FILE *in,FILE *out,char *line,int max,int pass){ } /* command line: - trainvq [vq=file | [entries=n] [dim=n]] met=n in=file,firstcol + trainvq [vq=file | [entries=n] [dim=n] [quant=n]] met=n in=file,firstcol [in=file,firstcol] */ @@ -87,7 +87,7 @@ void setexit(int dummy){ int main(int argc,char *argv[]){ vqgen v; - int entries=-1,dim=-1; + int entries=-1,dim=-1,quant=-1; FILE *out=NULL; int met=0; double (*metric)(vqgen *,double *, double *)=NULL; @@ -131,13 +131,13 @@ int main(int argc,char *argv[]){ double a; rline(in,out,line,160,1); - if(sscanf(line,"%d %d %d",&entries,&dim,&met)!=3){ + if(sscanf(line,"%d %d %d %d",&entries,&dim,&met,&quant)!=3){ fprintf(stderr,"Syntax error reading book file\n"); exit(1); } metric=set_metric(met); - vqgen_init(&v,dim,entries,metric,0.); + vqgen_init(&v,dim,entries,metric,quant); init=1; /* entries, bias, points */ @@ -177,6 +177,9 @@ int main(int argc,char *argv[]){ } /* set parameters if we're not loading a pre book */ + if(!strncmp(*argv,"quant=",6)){ + sscanf(*argv,"quant=%d",&quant); + } if(!strncmp(*argv,"entries=",8)){ sscanf(*argv,"entries=%d",&entries); } @@ -204,12 +207,12 @@ int main(int argc,char *argv[]){ exit(1); } if(!init){ - if(dim==-1 || entries==-1){ - fprintf(stderr,"Must specify dimensionality and entries before" + if(dim==-1 || entries==-1 || quant==-1){ + fprintf(stderr,"Must specify dimensionality,entries,quant before" " first input file\n"); exit(1); } - vqgen_init(&v,dim,entries,metric,0.); + vqgen_init(&v,dim,entries,metric,quant); init=1; } @@ -248,7 +251,7 @@ int main(int argc,char *argv[]){ /* save the book */ - fprintf(out,"%d %d %d\n",entries,dim,met); + fprintf(out,"%d %d %d %d\n",entries,dim,met,quant); i=0; for(j=0;jelements=elements; - v->errspread=spread; + v->quantbits=quant; v->allocated=32768; v->pointlist=malloc(v->allocated*v->elements*sizeof(double)); @@ -115,54 +115,6 @@ void vqgen_addpoint(vqgen *v, double *p){ if(v->points==v->entries)_vqgen_seed(v); } -/* take the trained entries, look at the points that comprise the cell - and find midpoints (as the actual encoding process uses euclidian - distance rather than any more complex metric to find the closest - match */ - -double *vqgen_midpoint(vqgen *v){ - long i,j,k; - double *lo=malloc(v->entries*v->elements*sizeof(double)); - double *hi=malloc(v->entries*v->elements*sizeof(double)); - - memset(v->assigned,0,sizeof(long)*v->entries); - for(i=0;ipoints;i++){ - double *ppt=_point(v,i); - double firstmetric=v->metric_func(v,_now(v,0),ppt)+v->bias[0]; - long firstentry=0; - for(j=1;jentries;j++){ - double thismetric=v->metric_func(v,_now(v,j),_point(v,i))+v->bias[j]; - if(thismetricassigned[j]++){ - for(k=0;kelements;k++){ - if(ppt[k]vN(hi,j)[k])vN(hi,j)[k]=ppt[k]; - } - }else{ - for(k=0;kelements;k++){ - vN(lo,j)[k]=ppt[k]; - vN(hi,j)[k]=ppt[k]; - } - } - } - - for(j=0;jentries;j++) - if(v->assigned[j]) - for(k=0;kelements;k++) - vN(lo,j)[k]=(vN(lo,j)[k]+vN(hi,j)[k])/2.; - else - for(k=0;kelements;k++) - vN(lo,j)[k]=_now(v,j)[k]; - free(hi); - return(lo); -} - double vqgen_iterate(vqgen *v){ long i,j,k; double fdesired=(double)v->points/v->entries; @@ -286,7 +238,8 @@ double vqgen_iterate(vqgen *v){ for(i=0;ientries;i++) v->bias[i]=nearbias[(i+1)*desired-1]; - /* last, assign midpoints */ + /* assign midpoints */ + for(j=0;jentries;j++){ asserror+=fabs(v->assigned[j]-fdesired); if(v->assigned[j]) @@ -298,6 +251,31 @@ double vqgen_iterate(vqgen *v){ #endif } + { + /* midpoints must be quantized. but we need to know the range in + order to do so */ + double *min=alloca(sizeof(double)*v->elements); + double *max=alloca(sizeof(double)*v->elements); + + for(k=0;kelements;k++) + min[k]=max[k]=_now(v,0)[k]; + for(j=1;jentries;j++){ + for(k=0;kelements;k++){ + double val=_now(v,0)[k]; + if(valmax[k])max[k]=val; + } + } + for(k=0;kelements;k++){ + double base=min[k]; + double delta=max[k]-min[k]/((1<quantbits)-1); + for(j=0;jentries;j++){ + double val=_now(v,j)[k]; + _now(v,j)[k]=rint((val-base)/delta); + } + } + } + asserror/=(v->entries*fdesired); fprintf(stderr,": dist %g(%g) metric error=%g \n", asserror,fdesired,meterror/v->points); diff --git a/vq/vqgen.h b/vq/vqgen.h new file mode 100644 index 0000000..6fcc54d --- /dev/null +++ b/vq/vqgen.h @@ -0,0 +1,70 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY * + * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. * + * PLEASE READ THESE TERMS DISTRIBUTING. * + * * + * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 * + * by 1999 Monty and The XIPHOPHORUS Company * + * http://www.xiph.org/ * + * * + ********************************************************************/ + +#ifndef _VQGEN_H_ +#define _VQGEN_H_ + +typedef struct vqgen{ + int it; + + int elements; + int quantbits; + + /* point cache */ + double *pointlist; + long points; + long allocated; + + /* entries */ + double *entrylist; + long *assigned; + double *bias; + long entries; + + double (*metric_func) (struct vqgen *v,double *a,double *b); +} vqgen; + +typedef struct vqbook{ + long elements; + long entries; + double *valuelist; + long *codelist; + long *lengthlist; + + /* auxiliary encoding/decoding information */ + long *ptr0; + long *ptr1; + + /* auxiliary encoding information */ + double *n; + double *c; + long aux; + long alloc; + +} vqbook; + +extern void vqgen_init(vqgen *v,int elements,int entries, + double (*metric)(vqgen *,double *, double *), + int quant); +extern void vqgen_addpoint(vqgen *v, double *p); +extern double *vqgen_midpoint(vqgen *v); +extern double vqgen_iterate(vqgen *v); +extern int vqenc_entry(vqbook *b,double *val); +extern void vqgen_book(vqgen *v,vqbook *b); + +#endif + + + + + -- 2.7.4