1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH 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.9 2000/10/12 03:13:02 xiphmont Exp $
17 ********************************************************************/
23 #include "vorbis/codebook.h"
24 #include "../lib/sharedbook.h"
27 /* collect the following metrics:
29 mean and mean squared amplitude
30 mean and mean squared error
31 mean and mean squared error (per sample) by entry
32 worst case fit by entry
37 (average bits per sample)*/
42 float meanamplitude_acc=0.;
43 float meanamplitudesq_acc=0.;
44 float meanerror_acc=0.;
45 float meanerrorsq_acc=0.;
47 float **histogram=NULL;
48 float **histogram_error=NULL;
49 float **histogram_errorsq=NULL;
50 float **histogram_hi=NULL;
51 float **histogram_lo=NULL;
55 static float *_now(codebook *c, int i){
56 return c->valuelist+i*c->c->dim;
61 void process_preprocess(codebook **bs,char *basename){
63 while(bs[books])books++;
66 histogram=calloc(books,sizeof(float *));
67 histogram_error=calloc(books,sizeof(float *));
68 histogram_errorsq=calloc(books,sizeof(float *));
69 histogram_hi=calloc(books,sizeof(float *));
70 histogram_lo=calloc(books,sizeof(float *));
72 fprintf(stderr,"Specify at least one codebook\n");
78 histogram[i]=calloc(b->entries,sizeof(float));
79 histogram_error[i]=calloc(b->entries*b->dim,sizeof(float));
80 histogram_errorsq[i]=calloc(b->entries*b->dim,sizeof(float));
81 histogram_hi[i]=calloc(b->entries*b->dim,sizeof(float));
82 histogram_lo[i]=calloc(b->entries*b->dim,sizeof(float));
86 static float _dist(int el,float *a, float *b){
90 float val=(a[i]-b[i]);
96 void cell_spacing(codebook *c){
98 float min=-1,max=-1,mean=0.,meansq=0.;
101 /* minimum, maximum, mean, ms cell spacing */
102 for(j=0;j<c->c->entries;j++){
103 if(c->c->lengthlist[j]>0){
105 for(k=0;k<c->c->entries;k++){
106 if(c->c->lengthlist[k]>0){
107 float this=_dist(c->c->dim,_now(c,j),_now(c,k));
109 (localmin==-1 || this<localmin))
114 if(min==-1 || localmin<min)min=localmin;
115 if(max==-1 || localmin>max)max=localmin;
116 mean+=sqrt(localmin);
122 fprintf(stderr,"\tminimum cell spacing (closest side): %g\n",sqrt(min));
123 fprintf(stderr,"\tmaximum cell spacing (closest side): %g\n",sqrt(max));
124 fprintf(stderr,"\tmean closest side spacing: %g\n",mean/total);
125 fprintf(stderr,"\tmean sq closest side spacing: %g\n",sqrt(meansq/total));
128 void process_postprocess(codebook **bs,char *basename){
130 char *buffer=alloca(strlen(basename)+80);
132 fprintf(stderr,"Done. Processed %ld data points:\n\n",
135 fprintf(stderr,"Global statistics:******************\n\n");
137 fprintf(stderr,"\ttotal samples: %ld\n",(long)count);
138 fprintf(stderr,"\ttotal bits required to code: %ld\n",(long)bits);
139 fprintf(stderr,"\taverage bits per sample: %g\n\n",bits/count);
141 fprintf(stderr,"\tmean sample amplitude: %g\n",
142 meanamplitude_acc/count);
143 fprintf(stderr,"\tmean squared sample amplitude: %g\n\n",
144 sqrt(meanamplitudesq_acc/count));
146 fprintf(stderr,"\tmean code error: %g\n",
147 meanerror_acc/count);
148 fprintf(stderr,"\tmean squared code error: %g\n\n",
149 sqrt(meanerrorsq_acc/count));
151 for(book=0;book<books;book++){
153 codebook *b=bs[book];
157 fprintf(stderr,"Book %d statistics:------------------\n",book);
161 sprintf(buffer,"%s-%d-mse.m",basename,book);
162 out=fopen(buffer,"w");
164 fprintf(stderr,"Could not open file %s for writing\n",buffer);
170 fprintf(out,"%d, %g, %g\n",
171 i*dim+k,(b->valuelist+i*dim)[k],
172 sqrt((histogram_errorsq[book]+i*dim)[k]/histogram[book][i]));
177 sprintf(buffer,"%s-%d-me.m",basename,book);
178 out=fopen(buffer,"w");
180 fprintf(stderr,"Could not open file %s for writing\n",buffer);
186 fprintf(out,"%d, %g, %g\n",
187 i*dim+k,(b->valuelist+i*dim)[k],
188 (histogram_error[book]+i*dim)[k]/histogram[book][i]);
193 sprintf(buffer,"%s-%d-worst.m",basename,book);
194 out=fopen(buffer,"w");
196 fprintf(stderr,"Could not open file %s for writing\n",buffer);
202 fprintf(out,"%d, %g, %g, %g\n",
203 i*dim+k,(b->valuelist+i*dim)[k],
204 (b->valuelist+i*dim)[k]+(histogram_lo[book]+i*dim)[k],
205 (b->valuelist+i*dim)[k]+(histogram_hi[book]+i*dim)[k]);
212 float process_one(codebook *b,int book,float *a,int dim,int step,int addmul,
220 amplitude=a[j*step]-(b->c->q_sequencep?last:0);
221 meanamplitude_acc+=fabs(amplitude);
222 meanamplitudesq_acc+=amplitude*amplitude;
228 if(b->c->q_sequencep){
237 entry=vorbis_book_besterror(b,a,step,addmul);
240 fprintf(stderr,"Internal error: _best returned -1.\n");
244 histogram[book][entry]++;
245 bits+=vorbis_book_codelen(b,entry);
248 float error=a[j*step];
251 meanerror_acc+=fabs(error);
252 meanerrorsq_acc+=error*error;
254 histogram_errorsq[book][entry*dim+j]+=error*error;
255 histogram_error[book][entry*dim+j]+=fabs(error);
256 if(histogram[book][entry]==0 || histogram_hi[book][entry*dim+j]<error)
257 histogram_hi[book][entry*dim+j]=error;
258 if(histogram[book][entry]==0 || histogram_lo[book][entry*dim+j]>error)
259 histogram_lo[book][entry*dim+j]=error;
265 void process_vector(codebook **bs,int *addmul,int inter,float *a,int n){
269 for(bi=0;bi<books;bi++){
276 base=process_one(b,bi,a+i,dim,n/dim,addmul[bi],base);
278 for(i=0;i<=n-dim;i+=dim)
279 base=process_one(b,bi,a+i,dim,1,addmul[bi],base);
283 if((long)(count)%100)spinnit("working.... samples: ",count);
286 void process_usage(void){
288 "usage: vqmetrics [-i] +|*<codebook>.vqh [ +|*<codebook.vqh> ]... \n"
289 " datafile.vqd [datafile.vqd]...\n\n"
290 " data can be taken on stdin. -i indicates interleaved coding.\n"
291 " Output goes to output files:\n"
292 " basename-me.m: gnuplot: mean error by entry value\n"
293 " basename-mse.m: gnuplot: mean square error by entry value\n"
294 " basename-worst.m: gnuplot: worst error by entry value\n"
295 " basename-distance.m: gnuplot file showing distance probability\n"