1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
6 * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
9 * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: function calls to collect codebook metrics
15 last mod: $Id: metrics.c,v 1.12 2000/12/21 21:04:49 xiphmont Exp $
17 ********************************************************************/
25 /* collect the following metrics:
27 mean and mean squared amplitude
28 mean and mean squared error
29 mean and mean squared error (per sample) by entry
30 worst case fit by entry
35 (average bits per sample)*/
40 float meanamplitude_acc=0.f;
41 float meanamplitudesq_acc=0.f;
42 float meanerror_acc=0.f;
43 float meanerrorsq_acc=0.f;
45 float **histogram=NULL;
46 float **histogram_error=NULL;
47 float **histogram_errorsq=NULL;
48 float **histogram_hi=NULL;
49 float **histogram_lo=NULL;
53 static float *_now(codebook *c, int i){
54 return c->valuelist+i*c->c->dim;
59 void process_preprocess(codebook **bs,char *basename){
61 while(bs[books])books++;
64 histogram=_ogg_calloc(books,sizeof(float *));
65 histogram_error=_ogg_calloc(books,sizeof(float *));
66 histogram_errorsq=_ogg_calloc(books,sizeof(float *));
67 histogram_hi=_ogg_calloc(books,sizeof(float *));
68 histogram_lo=_ogg_calloc(books,sizeof(float *));
70 fprintf(stderr,"Specify at least one codebook\n");
76 histogram[i]=_ogg_calloc(b->entries,sizeof(float));
77 histogram_error[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
78 histogram_errorsq[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
79 histogram_hi[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
80 histogram_lo[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
84 static float _dist(int el,float *a, float *b){
88 float val=(a[i]-b[i]);
94 void cell_spacing(codebook *c){
96 float min=-1.f,max=-1.f,mean=0.f,meansq=0.f;
99 /* minimum, maximum, mean, ms cell spacing */
100 for(j=0;j<c->c->entries;j++){
101 if(c->c->lengthlist[j]>0){
103 for(k=0;k<c->c->entries;k++){
104 if(c->c->lengthlist[k]>0){
105 float this=_dist(c->c->dim,_now(c,j),_now(c,k));
107 (localmin==-1 || this<localmin))
112 if(min==-1 || localmin<min)min=localmin;
113 if(max==-1 || localmin>max)max=localmin;
114 mean+=sqrt(localmin);
120 fprintf(stderr,"\tminimum cell spacing (closest side): %g\n",sqrt(min));
121 fprintf(stderr,"\tmaximum cell spacing (closest side): %g\n",sqrt(max));
122 fprintf(stderr,"\tmean closest side spacing: %g\n",mean/total);
123 fprintf(stderr,"\tmean sq closest side spacing: %g\n",sqrt(meansq/total));
126 void process_postprocess(codebook **bs,char *basename){
128 char *buffer=alloca(strlen(basename)+80);
130 fprintf(stderr,"Done. Processed %ld data points:\n\n",
133 fprintf(stderr,"Global statistics:******************\n\n");
135 fprintf(stderr,"\ttotal samples: %ld\n",(long)count);
136 fprintf(stderr,"\ttotal bits required to code: %ld\n",(long)bits);
137 fprintf(stderr,"\taverage bits per sample: %g\n\n",bits/count);
139 fprintf(stderr,"\tmean sample amplitude: %g\n",
140 meanamplitude_acc/count);
141 fprintf(stderr,"\tmean squared sample amplitude: %g\n\n",
142 sqrt(meanamplitudesq_acc/count));
144 fprintf(stderr,"\tmean code error: %g\n",
145 meanerror_acc/count);
146 fprintf(stderr,"\tmean squared code error: %g\n\n",
147 sqrt(meanerrorsq_acc/count));
149 for(book=0;book<books;book++){
151 codebook *b=bs[book];
155 fprintf(stderr,"Book %d statistics:------------------\n",book);
159 sprintf(buffer,"%s-%d-mse.m",basename,book);
160 out=fopen(buffer,"w");
162 fprintf(stderr,"Could not open file %s for writing\n",buffer);
168 fprintf(out,"%d, %g, %g\n",
169 i*dim+k,(b->valuelist+i*dim)[k],
170 sqrt((histogram_errorsq[book]+i*dim)[k]/histogram[book][i]));
175 sprintf(buffer,"%s-%d-me.m",basename,book);
176 out=fopen(buffer,"w");
178 fprintf(stderr,"Could not open file %s for writing\n",buffer);
184 fprintf(out,"%d, %g, %g\n",
185 i*dim+k,(b->valuelist+i*dim)[k],
186 (histogram_error[book]+i*dim)[k]/histogram[book][i]);
191 sprintf(buffer,"%s-%d-worst.m",basename,book);
192 out=fopen(buffer,"w");
194 fprintf(stderr,"Could not open file %s for writing\n",buffer);
200 fprintf(out,"%d, %g, %g, %g\n",
201 i*dim+k,(b->valuelist+i*dim)[k],
202 (b->valuelist+i*dim)[k]+(histogram_lo[book]+i*dim)[k],
203 (b->valuelist+i*dim)[k]+(histogram_hi[book]+i*dim)[k]);
210 float process_one(codebook *b,int book,float *a,int dim,int step,int addmul,
218 amplitude=a[j*step]-(b->c->q_sequencep?last:0);
219 meanamplitude_acc+=fabs(amplitude);
220 meanamplitudesq_acc+=amplitude*amplitude;
226 if(b->c->q_sequencep){
235 entry=vorbis_book_besterror(b,a,step,addmul);
238 fprintf(stderr,"Internal error: _best returned -1.\n");
242 histogram[book][entry]++;
243 bits+=vorbis_book_codelen(b,entry);
246 float error=a[j*step];
249 meanerror_acc+=fabs(error);
250 meanerrorsq_acc+=error*error;
252 histogram_errorsq[book][entry*dim+j]+=error*error;
253 histogram_error[book][entry*dim+j]+=fabs(error);
254 if(histogram[book][entry]==0 || histogram_hi[book][entry*dim+j]<error)
255 histogram_hi[book][entry*dim+j]=error;
256 if(histogram[book][entry]==0 || histogram_lo[book][entry*dim+j]>error)
257 histogram_lo[book][entry*dim+j]=error;
263 void process_vector(codebook **bs,int *addmul,int inter,float *a,int n){
267 for(bi=0;bi<books;bi++){
274 base=process_one(b,bi,a+i,dim,n/dim,addmul[bi],base);
276 for(i=0;i<=n-dim;i+=dim)
277 base=process_one(b,bi,a+i,dim,1,addmul[bi],base);
281 if((long)(count)%100)spinnit("working.... samples: ",count);
284 void process_usage(void){
286 "usage: vqmetrics [-i] +|*<codebook>.vqh [ +|*<codebook.vqh> ]... \n"
287 " datafile.vqd [datafile.vqd]...\n\n"
288 " data can be taken on stdin. -i indicates interleaved coding.\n"
289 " Output goes to output files:\n"
290 " basename-me.m: gnuplot: mean error by entry value\n"
291 " basename-mse.m: gnuplot: mean square error by entry value\n"
292 " basename-worst.m: gnuplot: worst error by entry value\n"
293 " basename-distance.m: gnuplot file showing distance probability\n"