1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
9 * by the Xiph.Org Foundation https://xiph.org/ *
11 ********************************************************************
13 function: function calls to collect codebook metrics
15 ********************************************************************/
23 /* collect the following metrics:
25 mean and mean squared amplitude
26 mean and mean squared error
27 mean and mean squared error (per sample) by entry
28 worst case fit by entry
33 (average bits per sample)*/
38 float meanamplitude_acc=0.f;
39 float meanamplitudesq_acc=0.f;
40 float meanerror_acc=0.f;
41 float meanerrorsq_acc=0.f;
43 float **histogram=NULL;
44 float **histogram_error=NULL;
45 float **histogram_errorsq=NULL;
46 float **histogram_hi=NULL;
47 float **histogram_lo=NULL;
51 static float *_now(codebook *c, int i){
52 return c->valuelist+i*c->c->dim;
57 void process_preprocess(codebook **bs,char *basename){
59 while(bs[books])books++;
62 histogram=_ogg_calloc(books,sizeof(float *));
63 histogram_error=_ogg_calloc(books,sizeof(float *));
64 histogram_errorsq=_ogg_calloc(books,sizeof(float *));
65 histogram_hi=_ogg_calloc(books,sizeof(float *));
66 histogram_lo=_ogg_calloc(books,sizeof(float *));
68 fprintf(stderr,"Specify at least one codebook\n");
74 histogram[i]=_ogg_calloc(b->entries,sizeof(float));
75 histogram_error[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
76 histogram_errorsq[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
77 histogram_hi[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
78 histogram_lo[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
82 static float _dist(int el,float *a, float *b){
86 float val=(a[i]-b[i]);
92 void cell_spacing(codebook *c){
94 float min=-1.f,max=-1.f,mean=0.f,meansq=0.f;
97 /* minimum, maximum, mean, ms cell spacing */
98 for(j=0;j<c->c->entries;j++){
99 if(c->c->lengthlist[j]>0){
101 for(k=0;k<c->c->entries;k++){
102 if(c->c->lengthlist[k]>0){
103 float this=_dist(c->c->dim,_now(c,j),_now(c,k));
105 (localmin==-1 || this<localmin))
110 if(min==-1 || localmin<min)min=localmin;
111 if(max==-1 || localmin>max)max=localmin;
112 mean+=sqrt(localmin);
118 fprintf(stderr,"\tminimum cell spacing (closest side): %g\n",sqrt(min));
119 fprintf(stderr,"\tmaximum cell spacing (closest side): %g\n",sqrt(max));
120 fprintf(stderr,"\tmean closest side spacing: %g\n",mean/total);
121 fprintf(stderr,"\tmean sq closest side spacing: %g\n",sqrt(meansq/total));
124 void process_postprocess(codebook **bs,char *basename){
126 char *buffer=alloca(strlen(basename)+80);
128 fprintf(stderr,"Done. Processed %ld data points:\n\n",
131 fprintf(stderr,"Global statistics:******************\n\n");
133 fprintf(stderr,"\ttotal samples: %ld\n",(long)count);
134 fprintf(stderr,"\ttotal bits required to code: %ld\n",(long)bits);
135 fprintf(stderr,"\taverage bits per sample: %g\n\n",bits/count);
137 fprintf(stderr,"\tmean sample amplitude: %g\n",
138 meanamplitude_acc/count);
139 fprintf(stderr,"\tmean squared sample amplitude: %g\n\n",
140 sqrt(meanamplitudesq_acc/count));
142 fprintf(stderr,"\tmean code error: %g\n",
143 meanerror_acc/count);
144 fprintf(stderr,"\tmean squared code error: %g\n\n",
145 sqrt(meanerrorsq_acc/count));
147 for(book=0;book<books;book++){
149 codebook *b=bs[book];
153 fprintf(stderr,"Book %d statistics:------------------\n",book);
157 sprintf(buffer,"%s-%d-mse.m",basename,book);
158 out=fopen(buffer,"w");
160 fprintf(stderr,"Could not open file %s for writing\n",buffer);
166 fprintf(out,"%d, %g, %g\n",
167 i*dim+k,(b->valuelist+i*dim)[k],
168 sqrt((histogram_errorsq[book]+i*dim)[k]/histogram[book][i]));
173 sprintf(buffer,"%s-%d-me.m",basename,book);
174 out=fopen(buffer,"w");
176 fprintf(stderr,"Could not open file %s for writing\n",buffer);
182 fprintf(out,"%d, %g, %g\n",
183 i*dim+k,(b->valuelist+i*dim)[k],
184 (histogram_error[book]+i*dim)[k]/histogram[book][i]);
189 sprintf(buffer,"%s-%d-worst.m",basename,book);
190 out=fopen(buffer,"w");
192 fprintf(stderr,"Could not open file %s for writing\n",buffer);
198 fprintf(out,"%d, %g, %g, %g\n",
199 i*dim+k,(b->valuelist+i*dim)[k],
200 (b->valuelist+i*dim)[k]+(histogram_lo[book]+i*dim)[k],
201 (b->valuelist+i*dim)[k]+(histogram_hi[book]+i*dim)[k]);
208 float process_one(codebook *b,int book,float *a,int dim,int step,int addmul,
216 amplitude=a[j*step]-(b->c->q_sequencep?last:0);
217 meanamplitude_acc+=fabs(amplitude);
218 meanamplitudesq_acc+=amplitude*amplitude;
224 if(b->c->q_sequencep){
233 entry=vorbis_book_besterror(b,a,step,addmul);
236 fprintf(stderr,"Internal error: _best returned -1.\n");
240 histogram[book][entry]++;
241 bits+=vorbis_book_codelen(b,entry);
244 float error=a[j*step];
247 meanerror_acc+=fabs(error);
248 meanerrorsq_acc+=error*error;
250 histogram_errorsq[book][entry*dim+j]+=error*error;
251 histogram_error[book][entry*dim+j]+=fabs(error);
252 if(histogram[book][entry]==0 || histogram_hi[book][entry*dim+j]<error)
253 histogram_hi[book][entry*dim+j]=error;
254 if(histogram[book][entry]==0 || histogram_lo[book][entry*dim+j]>error)
255 histogram_lo[book][entry*dim+j]=error;
261 void process_vector(codebook **bs,int *addmul,int inter,float *a,int n){
265 for(bi=0;bi<books;bi++){
272 base=process_one(b,bi,a+i,dim,n/dim,addmul[bi],base);
274 for(i=0;i<=n-dim;i+=dim)
275 base=process_one(b,bi,a+i,dim,1,addmul[bi],base);
279 if((long)(count)%100)spinnit("working.... samples: ",count);
282 void process_usage(void){
284 "usage: vqmetrics [-i] +|*<codebook>.vqh [ +|*<codebook.vqh> ]... \n"
285 " datafile.vqd [datafile.vqd]...\n\n"
286 " data can be taken on stdin. -i indicates interleaved coding.\n"
287 " Output goes to output files:\n"
288 " basename-me.m: gnuplot: mean error by entry value\n"
289 " basename-mse.m: gnuplot: mean square error by entry value\n"
290 " basename-worst.m: gnuplot: worst error by entry value\n"
291 " basename-distance.m: gnuplot file showing distance probability\n"