diff src/libvorbis-1.3.3/vq/latticebuild.c @ 86:98c1576536ae

Bring in flac, ogg, vorbis
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 19 Mar 2013 17:37:49 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libvorbis-1.3.3/vq/latticebuild.c	Tue Mar 19 17:37:49 2013 +0000
@@ -0,0 +1,177 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: utility main for building codebooks from lattice descriptions
+ last mod: $Id: latticebuild.c 16037 2009-05-26 21:10:58Z xiphmont $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <errno.h>
+#include "bookutil.h"
+
+/* The purpose of this util is just to finish packaging the
+   description into a static codebook.  It used to count hits for a
+   histogram, but I've divorced that out to add some flexibility (it
+   currently generates an equal probability codebook) 
+
+   command line:
+   latticebuild description.vql
+
+   the lattice description file contains two lines:
+
+   <n> <dim> <multiplicitavep> <sequentialp>
+   <value_0> <value_1> <value_2> ... <value_n-1>
+   
+   a threshmap (or pigeonmap) struct is generated by latticehint;
+   there are fun tricks one can do with the threshmap and cascades,
+   but the utils don't know them...
+
+   entropy encoding is done by feeding an entry list collected from a
+   training set and feeding it to latticetune along with the book.
+
+   latticebuild produces a codebook on stdout */
+
+static int ilog(unsigned int v){
+  int ret=0;
+  while(v){
+    ret++;
+    v>>=1;
+  }
+  return(ret);
+}
+
+int main(int argc,char *argv[]){
+  codebook b;
+  static_codebook c;
+  double *quantlist;
+  long *hits;
+
+  int entries=-1,dim=-1,quantvals=-1,addmul=-1,sequencep=0;
+  FILE *in=NULL;
+  char *line,*name;
+  long i,j;
+
+  memset(&b,0,sizeof(b));
+  memset(&c,0,sizeof(c));
+
+  if(argv[1]==NULL){
+    fprintf(stderr,"Need a lattice description file on the command line.\n");
+    exit(1);
+  }
+
+  {
+    char *ptr;
+    char *filename=_ogg_calloc(strlen(argv[1])+4,1);
+
+    strcpy(filename,argv[1]);
+    in=fopen(filename,"r");
+    if(!in){
+      fprintf(stderr,"Could not open input file %s\n",filename);
+      exit(1);
+    }
+    
+    ptr=strrchr(filename,'.');
+    if(ptr){
+      *ptr='\0';
+      name=strdup(filename);
+    }else{
+      name=strdup(filename);
+    }
+
+  }
+  
+  /* read the description */
+  line=get_line(in);
+  if(sscanf(line,"%d %d %d %d",&quantvals,&dim,&addmul,&sequencep)!=4){
+    if(sscanf(line,"%d %d %d",&quantvals,&dim,&addmul)!=3){
+      fprintf(stderr,"Syntax error reading description file (line 1)\n");
+      exit(1);
+    }
+  }
+  entries=pow(quantvals,dim);
+  c.dim=dim;
+  c.entries=entries;
+  c.lengthlist=_ogg_malloc(entries*sizeof(long));
+  c.maptype=1;
+  c.q_sequencep=sequencep;
+  c.quantlist=_ogg_calloc(quantvals,sizeof(long));
+
+  quantlist=_ogg_malloc(sizeof(double)*c.dim*c.entries);
+  hits=_ogg_malloc(c.entries*sizeof(long));
+  for(j=0;j<entries;j++)hits[j]=1;
+  for(j=0;j<entries;j++)c.lengthlist[j]=1;
+
+  reset_next_value();
+  line=setup_line(in);
+  for(j=0;j<quantvals;j++){ 
+    char *temp;
+    if(!line || sscanf(line,"%lf",quantlist+j)!=1){
+      fprintf(stderr,"Ran out of data on line 2 of description file\n");
+      exit(1);
+    }
+    temp=strchr(line,',');
+    if(!temp)temp=strchr(line,' ');
+    if(temp)temp++;
+    line=temp;
+  }
+
+  /* gen a real quant list from the more easily human-grokked input */
+  {
+    double min=quantlist[0];
+    double mindel=-1;
+    int fac=1;
+    for(j=1;j<quantvals;j++)if(quantlist[j]<min)min=quantlist[j];
+    for(j=0;j<quantvals;j++)
+      for(i=j+1;i<quantvals;i++)
+        if(mindel==-1 || fabs(quantlist[j]-quantlist[i])<mindel)
+          mindel=fabs(quantlist[j]-quantlist[i]);
+
+    j=0;
+    while(j<quantvals){
+      for(j=0;j<quantvals;j++){
+        double test=fac*(quantlist[j]-min)/mindel;
+        if( fabs(rint(test)-test)>.00001f) break;
+      }
+      if(fac>100)break;
+      if(j<quantvals)fac++;
+    }
+
+    mindel/=fac;
+    fprintf(stderr,"min=%g mindel=%g\n",min,mindel);
+
+    c.q_min=_float32_pack(min);
+    c.q_delta=_float32_pack(mindel);
+    c.q_quant=0;
+
+    min=_float32_unpack(c.q_min);
+    mindel=_float32_unpack(c.q_delta);
+    for(j=0;j<quantvals;j++){
+      c.quantlist[j]=rint((quantlist[j]-min)/mindel);
+      if(ilog(c.quantlist[j])>c.q_quant)c.q_quant=ilog(c.quantlist[j]);
+    }
+  }
+
+  /* build the [default] codeword lengths */
+  memset(c.lengthlist,0,sizeof(long)*entries);
+  for(i=0;i<entries;i++)hits[i]=1;
+  build_tree_from_lengths(entries,hits,c.lengthlist);
+
+  /* save the book in C header form */
+  write_codebook(stdout,name,&c);
+  fprintf(stderr,"\r                                                     "
+          "\nDone.\n");
+  exit(0);
+}