18e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/********************************************************************
28e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
38e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
48e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
58e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
68e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
78e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
88e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
98e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * by the Xiph.Org Foundation http://www.xiph.org/                  *
108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************
128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels function: function calls to collect codebook metrics
148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels last mod: $Id: metrics.c 16037 2009-05-26 21:10:58Z xiphmont $
158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************/
178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdlib.h>
208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <unistd.h>
218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <math.h>
228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "bookutil.h"
238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* collect the following metrics:
258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   mean and mean squared amplitude
278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   mean and mean squared error
288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   mean and mean squared error (per sample) by entry
298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   worst case fit by entry
308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   entry cell size
318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   hits by entry
328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   total bits
338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   total samples
348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   (average bits per sample)*/
358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* set up metrics */
388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat meanamplitude_acc=0.f;
408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat meanamplitudesq_acc=0.f;
418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat meanerror_acc=0.f;
428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat meanerrorsq_acc=0.f;
438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat **histogram=NULL;
458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat **histogram_error=NULL;
468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat **histogram_errorsq=NULL;
478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat **histogram_hi=NULL;
488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat **histogram_lo=NULL;
498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat bits=0.f;
508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat count=0.f;
518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic float *_now(codebook *c, int i){
538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return c->valuelist+i*c->c->dim;
548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint books=0;
578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid process_preprocess(codebook **bs,char *basename){
598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(bs[books])books++;
618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(books){
638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram=_ogg_calloc(books,sizeof(float *));
648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram_error=_ogg_calloc(books,sizeof(float *));
658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram_errorsq=_ogg_calloc(books,sizeof(float *));
668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram_hi=_ogg_calloc(books,sizeof(float *));
678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram_lo=_ogg_calloc(books,sizeof(float *));
688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fprintf(stderr,"Specify at least one codebook\n");
708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    exit(1);
718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<books;i++){
748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    codebook *b=bs[i];
758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram[i]=_ogg_calloc(b->entries,sizeof(float));
768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram_error[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram_errorsq[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram_hi[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram_lo[i]=_ogg_calloc(b->entries*b->dim,sizeof(float));
808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic float _dist(int el,float *a, float *b){
848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float acc=0.f;
868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<el;i++){
878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float val=(a[i]-b[i]);
888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    acc+=val*val;
898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return acc;
918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid cell_spacing(codebook *c){
948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j,k;
958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float min=-1.f,max=-1.f,mean=0.f,meansq=0.f;
968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long total=0;
978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* minimum, maximum, mean, ms cell spacing */
998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<c->c->entries;j++){
1008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(c->c->lengthlist[j]>0){
1018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      float localmin=-1.;
1028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<c->c->entries;k++){
1038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(c->c->lengthlist[k]>0){
1048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          float this=_dist(c->c->dim,_now(c,j),_now(c,k));
1058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(j!=k &&
1068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels             (localmin==-1 || this<localmin))
1078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            localmin=this;
1088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
1098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
1108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(min==-1 || localmin<min)min=localmin;
1128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(max==-1 || localmin>max)max=localmin;
1138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      mean+=sqrt(localmin);
1148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      meansq+=localmin;
1158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      total++;
1168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\tminimum cell spacing (closest side): %g\n",sqrt(min));
1208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\tmaximum cell spacing (closest side): %g\n",sqrt(max));
1218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\tmean closest side spacing: %g\n",mean/total);
1228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\tmean sq closest side spacing: %g\n",sqrt(meansq/total));
1238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid process_postprocess(codebook **bs,char *basename){
1268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,k,book;
1278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  char *buffer=alloca(strlen(basename)+80);
1288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"Done.  Processed %ld data points:\n\n",
1308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          (long)count);
1318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"Global statistics:******************\n\n");
1338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\ttotal samples: %ld\n",(long)count);
1358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\ttotal bits required to code: %ld\n",(long)bits);
1368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\taverage bits per sample: %g\n\n",bits/count);
1378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\tmean sample amplitude: %g\n",
1398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          meanamplitude_acc/count);
1408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\tmean squared sample amplitude: %g\n\n",
1418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          sqrt(meanamplitudesq_acc/count));
1428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\tmean code error: %g\n",
1448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          meanerror_acc/count);
1458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,"\tmean squared code error: %g\n\n",
1468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          sqrt(meanerrorsq_acc/count));
1478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(book=0;book<books;book++){
1498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    FILE *out;
1508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    codebook *b=bs[book];
1518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int n=b->c->entries;
1528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int dim=b->c->dim;
1538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fprintf(stderr,"Book %d statistics:------------------\n",book);
1558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    cell_spacing(b);
1578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    sprintf(buffer,"%s-%d-mse.m",basename,book);
1598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    out=fopen(buffer,"w");
1608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(!out){
1618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      fprintf(stderr,"Could not open file %s for writing\n",buffer);
1628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      exit(1);
1638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<n;i++){
1668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<dim;k++){
1678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        fprintf(out,"%d, %g, %g\n",
1688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                i*dim+k,(b->valuelist+i*dim)[k],
1698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                sqrt((histogram_errorsq[book]+i*dim)[k]/histogram[book][i]));
1708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
1718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fclose(out);
1738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    sprintf(buffer,"%s-%d-me.m",basename,book);
1758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    out=fopen(buffer,"w");
1768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(!out){
1778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      fprintf(stderr,"Could not open file %s for writing\n",buffer);
1788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      exit(1);
1798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<n;i++){
1828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<dim;k++){
1838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        fprintf(out,"%d, %g, %g\n",
1848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                i*dim+k,(b->valuelist+i*dim)[k],
1858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                (histogram_error[book]+i*dim)[k]/histogram[book][i]);
1868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
1878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fclose(out);
1898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    sprintf(buffer,"%s-%d-worst.m",basename,book);
1918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    out=fopen(buffer,"w");
1928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(!out){
1938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      fprintf(stderr,"Could not open file %s for writing\n",buffer);
1948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      exit(1);
1958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<n;i++){
1988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<dim;k++){
1998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        fprintf(out,"%d, %g, %g, %g\n",
2008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                i*dim+k,(b->valuelist+i*dim)[k],
2018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                (b->valuelist+i*dim)[k]+(histogram_lo[book]+i*dim)[k],
2028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                (b->valuelist+i*dim)[k]+(histogram_hi[book]+i*dim)[k]);
2038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
2048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fclose(out);
2068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsfloat process_one(codebook *b,int book,float *a,int dim,int step,int addmul,
2108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                   float base){
2118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j,entry;
2128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float amplitude=0.f;
2138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(book==0){
2158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float last=base;
2168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<dim;j++){
2178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      amplitude=a[j*step]-(b->c->q_sequencep?last:0);
2188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      meanamplitude_acc+=fabs(amplitude);
2198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      meanamplitudesq_acc+=amplitude*amplitude;
2208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      count++;
2218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      last=a[j*step];
2228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(b->c->q_sequencep){
2268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float temp;
2278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<dim;j++){
2288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      temp=a[j*step];
2298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      a[j*step]-=base;
2308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    base=temp;
2328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  entry=vorbis_book_besterror(b,a,step,addmul);
2358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(entry==-1){
2378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fprintf(stderr,"Internal error: _best returned -1.\n");
2388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    exit(1);
2398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  histogram[book][entry]++;
2428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  bits+=vorbis_book_codelen(b,entry);
2438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<dim;j++){
2458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float error=a[j*step];
2468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(book==books-1){
2488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      meanerror_acc+=fabs(error);
2498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      meanerrorsq_acc+=error*error;
2508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram_errorsq[book][entry*dim+j]+=error*error;
2528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    histogram_error[book][entry*dim+j]+=fabs(error);
2538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(histogram[book][entry]==0 || histogram_hi[book][entry*dim+j]<error)
2548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      histogram_hi[book][entry*dim+j]=error;
2558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(histogram[book][entry]==0 || histogram_lo[book][entry*dim+j]>error)
2568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      histogram_lo[book][entry*dim+j]=error;
2578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return base;
2598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid process_vector(codebook **bs,int *addmul,int inter,float *a,int n){
2638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int bi;
2648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
2658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(bi=0;bi<books;bi++){
2678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    codebook *b=bs[bi];
2688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int dim=b->dim;
2698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    float base=0.f;
2708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(inter){
2728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<n/dim;i++)
2738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        base=process_one(b,bi,a+i,dim,n/dim,addmul[bi],base);
2748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
2758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0;i<=n-dim;i+=dim)
2768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        base=process_one(b,bi,a+i,dim,1,addmul[bi],base);
2778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if((long)(count)%100)spinnit("working.... samples: ",count);
2818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid process_usage(void){
2848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(stderr,
2858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          "usage: vqmetrics [-i] +|*<codebook>.vqh [ +|*<codebook.vqh> ]... \n"
2868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          "                 datafile.vqd [datafile.vqd]...\n\n"
2878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          "       data can be taken on stdin.  -i indicates interleaved coding.\n"
2888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          "       Output goes to output files:\n"
2898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          "       basename-me.m:       gnuplot: mean error by entry value\n"
2908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          "       basename-mse.m:      gnuplot: mean square error by entry value\n"
2918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          "       basename-worst.m:    gnuplot: worst error by entry value\n"
2928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          "       basename-distance.m: gnuplot file showing distance probability\n"
2938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          "\n");
2948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
296