X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=vq%2Fvqgen.c;h=934d26420b36ee33af9bcea995ae682283ad889e;hb=be4c6130022e014277864b93725557d79f37af73;hp=63a9d861d5a83cc16c0c9d850f066a406d5019cf;hpb=b6dd3d990ac5e3c8a9b9143cbc80f86cbca361a8;p=platform%2Fupstream%2Flibvorbis.git diff --git a/vq/vqgen.c b/vq/vqgen.c index 63a9d86..934d264 100644 --- a/vq/vqgen.c +++ b/vq/vqgen.c @@ -1,18 +1,16 @@ /******************************************************************** * * * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY * - * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH * - * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 * - * by Monty and the XIPHOPHORUS Company * - * http://www.xiph.org/ * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** - function: train a VQ codebook - last mod: $Id: vqgen.c,v 1.37 2000/12/21 21:04:49 xiphmont Exp $ + function: train a VQ codebook ********************************************************************/ @@ -33,13 +31,13 @@ #include "vqgen.h" #include "bookutil.h" -/* Codebook generation happens in two steps: +/* Codebook generation happens in two steps: 1) Train the codebook with data collected from the encoder: We use one of a few error metrics (which represent the distance between a given data point and a candidate point in the training set) to divide the training set up into cells representing roughly equal - probability of occurring. + probability of occurring. 2) Generate the codebook and auxiliary data from the trained data set */ @@ -84,8 +82,7 @@ void _vqgen_seed(vqgen *v){ int directdsort(const void *a, const void *b){ float av=*((float *)a); float bv=*((float *)b); - if(av>bv)return(-1); - return(1); + return (avbv); } void vqgen_cellmetric(vqgen *v){ @@ -108,16 +105,16 @@ void vqgen_cellmetric(vqgen *v){ for(k=0;kentries;k++){ if(j!=k){ - float this=_dist(v,_now(v,j),_now(v,k)); - if(this>0){ - if(v->assigned[k] && (localmin==-1 || this0){ + if(v->assigned[k] && (localmin==-1 || thisentries)continue; @@ -126,7 +123,7 @@ void vqgen_cellmetric(vqgen *v){ unused++; continue; } - + localmin=v->max[j]+localmin/2; /* this gives us rough diameter */ if(min==-1 || localminmax)max=localmin; @@ -138,14 +135,14 @@ void vqgen_cellmetric(vqgen *v){ } fprintf(stderr,"cell diameter: %.03g::%.03g::%.03g (%ld unused/%ld dup)\n", - min,mean/acc,max,unused,dup); + min,mean/acc,max,unused,dup); #ifdef NOISY qsort(spacings,count,sizeof(float),directdsort); for(i=0;ientries;j++){ float last=0.f; for(k=0;kelements;k++){ @@ -203,18 +200,18 @@ void vqgen_quantize(vqgen *v,quant_meta *q){ for(k=0;kelements;k++){ float val=_now(v,j)[k]; float now=rint((val-last-mindel)/delta); - + _now(v,j)[k]=now; if(now<0){ - /* be paranoid; this should be impossible */ - fprintf(stderr,"fault; quantized value<0\n"); - exit(1); + /* be paranoid; this should be impossible */ + fprintf(stderr,"fault; quantized value<0\n"); + exit(1); } if(now>maxquant){ - /* be paranoid; this should be impossible */ - fprintf(stderr,"fault; quantized value>max\n"); - exit(1); + /* be paranoid; this should be impossible */ + fprintf(stderr,"fault; quantized value>max\n"); + exit(1); } if(q->sequencep)last=(now*delta)+mindel+last; } @@ -240,8 +237,8 @@ void vqgen_unquantize(vqgen *v,quant_meta *q){ } void vqgen_init(vqgen *v,int elements,int aux,int entries,float mindist, - float (*metric)(vqgen *,float *, float *), - float *(*weight)(vqgen *,float *),int centroid){ + float (*metric)(vqgen *,float *, float *), + float *(*weight)(vqgen *,float *),int centroid){ memset(v,0,sizeof(vqgen)); v->centroid=centroid; @@ -279,18 +276,18 @@ void vqgen_addpoint(vqgen *v, float *p,float *a){ if(v->points>=v->allocated){ v->allocated*=2; v->pointlist=_ogg_realloc(v->pointlist,v->allocated*(v->elements+v->aux)* - sizeof(float)); + sizeof(float)); } memcpy(_point(v,v->points),p,sizeof(float)*v->elements); if(v->aux)memcpy(_point(v,v->points)+v->elements,a,sizeof(float)*v->aux); - + /* quantize to the density mesh if it's selected */ if(v->mindist>0.f){ /* quantize to the mesh */ for(k=0;kelements+v->aux;k++) _point(v,v->points)[k]= - rint(_point(v,v->points)[k]/v->mindist)*v->mindist; + rint(_point(v,v->points)[k]/v->mindist)*v->mindist; } v->points++; if(!(v->points&0xff))spinnit("loading... ",v->points); @@ -316,16 +313,16 @@ void vqgen_sortmesh(vqgen *v){ /* now march through and eliminate dupes */ for(i=1;ipoints;i++){ if(memcmp(_point(v,i),_point(v,i-1),sortsize)){ - /* a new, unique entry. march it down */ - if(i>march)memcpy(_point(v,march),_point(v,i),sortsize); - march++; + /* a new, unique entry. march it down */ + if(i>march)memcpy(_point(v,march),_point(v,i),sortsize); + march++; } spinnit("eliminating density... ",v->points-i); } /* we're done */ fprintf(stderr,"\r%ld training points remining out of %ld" - " after density mesh (%ld%%)\n",march,v->points,march*100/v->points); + " after density mesh (%ld%%)\n",march,v->points,march*100/v->points); v->points=march; } @@ -357,7 +354,7 @@ float vqgen_iterate(vqgen *v,int biasp){ sprintf(buff,"bias%d.m",v->it); bias=fopen(buff,"w"); #endif - + if(v->entries<2){ fprintf(stderr,"generation requires at least two entries\n"); @@ -386,91 +383,91 @@ float vqgen_iterate(vqgen *v,int biasp){ float secondmetric=v->metric_func(v,_now(v,1),ppt)+v->bias[1]; long firstentry=0; long secondentry=1; - + if(!(i&0xff))spinnit("biasing... ",v->points+v->points+v->entries-i); - + if(firstmetric>secondmetric){ - float temp=firstmetric; - firstmetric=secondmetric; - secondmetric=temp; - firstentry=1; - secondentry=0; + float temp=firstmetric; + firstmetric=secondmetric; + secondmetric=temp; + firstentry=1; + secondentry=0; } - + for(j=2;jentries;j++){ - float thismetric=v->metric_func(v,_now(v,j),ppt)+v->bias[j]; - if(thismetricmetric_func(v,_now(v,j),ppt)+v->bias[j]; + if(thismetricentries;j++){ - - float thismetric,localmetric; - float *nearbiasptr=nearbias+desired2*j; - long k=nearcount[j]; - - localmetric=v->metric_func(v,_now(v,j),ppt); - /* 'thismetric' is to be the bias value necessary in the current - arrangement for entry j to capture point i */ - if(firstentry==j){ - /* use the secondary entry as the threshhold */ - thismetric=secondmetric-localmetric; - }else{ - /* use the primary entry as the threshhold */ - thismetric=firstmetric-localmetric; - } - - /* support the idea of 'minimum distance'... if we want the - cells in a codebook to be roughly some minimum size (as with - the low resolution residue books) */ - - /* a cute two-stage delayed sorting hack */ - if(kpoints+v->points+v->entries-i); - qsort(nearbiasptr,desired,sizeof(float),directdsort); - } - - }else if(thismetric>nearbiasptr[desired-1]){ - nearbiasptr[k]=thismetric; - k++; - if(k==desired2){ - spinnit("biasing... ",v->points+v->points+v->entries-i); - qsort(nearbiasptr,desired2,sizeof(float),directdsort); - k=desired; - } - } - nearcount[j]=k; + + float thismetric,localmetric; + float *nearbiasptr=nearbias+desired2*j; + long k=nearcount[j]; + + localmetric=v->metric_func(v,_now(v,j),ppt); + /* 'thismetric' is to be the bias value necessary in the current + arrangement for entry j to capture point i */ + if(firstentry==j){ + /* use the secondary entry as the threshhold */ + thismetric=secondmetric-localmetric; + }else{ + /* use the primary entry as the threshhold */ + thismetric=firstmetric-localmetric; + } + + /* support the idea of 'minimum distance'... if we want the + cells in a codebook to be roughly some minimum size (as with + the low resolution residue books) */ + + /* a cute two-stage delayed sorting hack */ + if(kpoints+v->points+v->entries-i); + qsort(nearbiasptr,desired,sizeof(float),directdsort); + } + + }else if(thismetric>nearbiasptr[desired-1]){ + nearbiasptr[k]=thismetric; + k++; + if(k==desired2){ + spinnit("biasing... ",v->points+v->points+v->entries-i); + qsort(nearbiasptr,desired2,sizeof(float),directdsort); + k=desired; + } + } + nearcount[j]=k; } } - + /* inflate/deflate */ - + for(i=0;ientries;i++){ float *nearbiasptr=nearbias+desired2*i; - + spinnit("biasing... ",v->points+v->entries-i); - + /* due to the delayed sorting, we likely need to finish it off....*/ if(nearcount[i]>desired) - qsort(nearbiasptr,nearcount[i],sizeof(float),directdsort); + qsort(nearbiasptr,nearcount[i],sizeof(float),directdsort); v->bias[i]=nearbiasptr[desired-1]; } - }else{ + }else{ memset(v->bias,0,v->entries*sizeof(float)); } @@ -485,13 +482,13 @@ float vqgen_iterate(vqgen *v,int biasp){ for(j=0;jentries;j++){ float thismetric=v->metric_func(v,_now(v,j),ppt)+v->bias[j]; if(thismetriccentroid==0){ /* set up midpoints for next iter */ if(v->assigned[j]++){ - for(k=0;kelements;k++) - vN(new,j)[k]+=ppt[k]; - if(firstmetric>v->max[j])v->max[j]=firstmetric; + for(k=0;kelements;k++) + vN(new,j)[k]+=ppt[k]; + if(firstmetric>v->max[j])v->max[j]=firstmetric; }else{ - for(k=0;kelements;k++) - vN(new,j)[k]=ppt[k]; - v->max[j]=firstmetric; + for(k=0;kelements;k++) + vN(new,j)[k]=ppt[k]; + v->max[j]=firstmetric; } }else{ /* centroid */ if(v->assigned[j]++){ - for(k=0;kelements;k++){ - if(vN(new,j)[k]>ppt[k])vN(new,j)[k]=ppt[k]; - if(vN(new2,j)[k]v->max[firstentry])v->max[j]=firstmetric; + for(k=0;kelements;k++){ + if(vN(new,j)[k]>ppt[k])vN(new,j)[k]=ppt[k]; + if(vN(new2,j)[k]v->max[firstentry])v->max[j]=firstmetric; }else{ - for(k=0;kelements;k++){ - vN(new,j)[k]=ppt[k]; - vN(new2,j)[k]=ppt[k]; - } - v->max[firstentry]=firstmetric; + for(k=0;kelements;k++){ + vN(new,j)[k]=ppt[k]; + vN(new2,j)[k]=ppt[k]; + } + v->max[firstentry]=firstmetric; } } } @@ -540,11 +537,11 @@ float vqgen_iterate(vqgen *v,int biasp){ asserror+=fabs(v->assigned[j]-fdesired); if(v->assigned[j]){ if(v->centroid==0){ - for(k=0;kelements;k++) - _now(v,j)[k]=vN(new,j)[k]/v->assigned[j]; + for(k=0;kelements;k++) + _now(v,j)[k]=vN(new,j)[k]/v->assigned[j]; }else{ - for(k=0;kelements;k++) - _now(v,j)[k]=(vN(new,j)[k]+vN(new2,j)[k])/2.f; + for(k=0;kelements;k++) + _now(v,j)[k]=(vN(new,j)[k]+vN(new2,j)[k])/2.f; } } } @@ -553,9 +550,9 @@ float vqgen_iterate(vqgen *v,int biasp){ fprintf(stderr,"Pass #%d... ",v->it); fprintf(stderr,": dist %g(%g) metric error=%g \n", - asserror,fdesired,meterror/v->points); + asserror,fdesired,meterror/v->points); v->it++; - + free(new); free(nearcount); free(nearbias);