diff options
author | Aki <please@ignore.pl> | 2021-09-29 22:52:49 +0200 |
---|---|---|
committer | Aki <please@ignore.pl> | 2021-09-29 22:52:49 +0200 |
commit | 760f65d35df281b04d99843958623d99ab35dcaf (patch) | |
tree | 76f6f05695822256bbf8097fa0aa6b5d2a34369b /vorbis/vq/latticebuild.c | |
parent | bdb934044a10bcccdea4ae5e9b067a2e764e0e7f (diff) | |
parent | 74f4b1bc3b627ba4c7e03498234d88cacdfbe97b (diff) | |
download | starshatter-760f65d35df281b04d99843958623d99ab35dcaf.zip starshatter-760f65d35df281b04d99843958623d99ab35dcaf.tar.gz starshatter-760f65d35df281b04d99843958623d99ab35dcaf.tar.bz2 |
Merge commit '74f4b1bc3b627ba4c7e03498234d88cacdfbe97b' as 'vorbis'
Diffstat (limited to 'vorbis/vq/latticebuild.c')
-rw-r--r-- | vorbis/vq/latticebuild.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/vorbis/vq/latticebuild.c b/vorbis/vq/latticebuild.c new file mode 100644 index 0000000..acfe9ff --- /dev/null +++ b/vorbis/vq/latticebuild.c @@ -0,0 +1,176 @@ +/******************************************************************** + * * + * 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 + + ********************************************************************/ + +#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); +} |