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.7 2000/05/08 20:49:50 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 double meanamplitude_acc=0.;
43 double meanamplitudesq_acc=0.;
44 double meanerror_acc=0.;
45 double meanerrorsq_acc=0.;
47 double **histogram=NULL;
48 double **histogram_error=NULL;
49 double **histogram_errorsq=NULL;
50 double **histogram_hi=NULL;
51 double **histogram_lo=NULL;
55 static double *_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(double *));
67 histogram_error=calloc(books,sizeof(double *));
68 histogram_errorsq=calloc(books,sizeof(double *));
69 histogram_hi=calloc(books,sizeof(double *));
70 histogram_lo=calloc(books,sizeof(double *));
72 fprintf(stderr,"Specify at least one codebook\n");
78 histogram[i]=calloc(b->entries,sizeof(double));
79 histogram_error[i]=calloc(b->entries*b->dim,sizeof(double));
80 histogram_errorsq[i]=calloc(b->entries*b->dim,sizeof(double));
81 histogram_hi[i]=calloc(b->entries*b->dim,sizeof(double));
82 histogram_lo[i]=calloc(b->entries*b->dim,sizeof(double));
86 static double _dist(int el,double *a, double *b){
90 double val=(a[i]-b[i]);
96 void cell_spacing(codebook *c){
98 double 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 double 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 double process_one(codebook *b,int book,double *a,int dim,int step,int addmul,
220 amplitude=a[j*step]-last;
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);
239 histogram[book][entry]++;
240 bits+=vorbis_book_codelen(b,entry);
243 double error=a[j*step];
246 meanerror_acc+=fabs(error);
247 meanerrorsq_acc+=error*error;
249 histogram_errorsq[book][entry*dim+j]+=error*error;
250 histogram_error[book][entry*dim+j]+=fabs(error);
251 if(histogram[book][entry]==0 || histogram_hi[book][entry*dim+j]<error)
252 histogram_hi[book][entry*dim+j]=error;
253 if(histogram[book][entry]==0 || histogram_lo[book][entry*dim+j]>error)
254 histogram_lo[book][entry*dim+j]=error;
260 void process_vector(codebook **bs,int *addmul,int inter,double *a,int n){
264 for(bi=0;bi<books;bi++){
271 base=process_one(b,bi,a+i,dim,n/dim,addmul[bi],base);
273 for(i=0;i<=n-dim;i+=dim)
274 base=process_one(b,bi,a+i,dim,1,addmul[bi],base);
278 if((long)(count)%100)spinnit("working.... samples: ",count);
281 void process_usage(void){
283 "usage: vqmetrics [-i] +|*<codebook>.vqh [ +|*<codebook.vqh> ]... \n"
284 " datafile.vqd [datafile.vqd]...\n\n"
285 " data can be taken on stdin. -i indicates interleaved coding.\n"
286 " Output goes to output files:\n"
287 " basename-me.m: gnuplot: mean error by entry value\n"
288 " basename-mse.m: gnuplot: mean square error by entry value\n"
289 " basename-worst.m: gnuplot: worst error by entry value\n"
290 " basename-distance.m: gnuplot file showing distance probability\n"