Mercurial > hg > sv-dependency-builds
comparison 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 |
comparison
equal
deleted
inserted
replaced
85:545efbb81310 | 86:98c1576536ae |
---|---|
1 /******************************************************************** | |
2 * * | |
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. * | |
7 * * | |
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * | |
9 * by the Xiph.Org Foundation http://www.xiph.org/ * | |
10 * * | |
11 ******************************************************************** | |
12 | |
13 function: utility main for building codebooks from lattice descriptions | |
14 last mod: $Id: latticebuild.c 16037 2009-05-26 21:10:58Z xiphmont $ | |
15 | |
16 ********************************************************************/ | |
17 | |
18 #include <stdlib.h> | |
19 #include <stdio.h> | |
20 #include <math.h> | |
21 #include <string.h> | |
22 #include <errno.h> | |
23 #include "bookutil.h" | |
24 | |
25 /* The purpose of this util is just to finish packaging the | |
26 description into a static codebook. It used to count hits for a | |
27 histogram, but I've divorced that out to add some flexibility (it | |
28 currently generates an equal probability codebook) | |
29 | |
30 command line: | |
31 latticebuild description.vql | |
32 | |
33 the lattice description file contains two lines: | |
34 | |
35 <n> <dim> <multiplicitavep> <sequentialp> | |
36 <value_0> <value_1> <value_2> ... <value_n-1> | |
37 | |
38 a threshmap (or pigeonmap) struct is generated by latticehint; | |
39 there are fun tricks one can do with the threshmap and cascades, | |
40 but the utils don't know them... | |
41 | |
42 entropy encoding is done by feeding an entry list collected from a | |
43 training set and feeding it to latticetune along with the book. | |
44 | |
45 latticebuild produces a codebook on stdout */ | |
46 | |
47 static int ilog(unsigned int v){ | |
48 int ret=0; | |
49 while(v){ | |
50 ret++; | |
51 v>>=1; | |
52 } | |
53 return(ret); | |
54 } | |
55 | |
56 int main(int argc,char *argv[]){ | |
57 codebook b; | |
58 static_codebook c; | |
59 double *quantlist; | |
60 long *hits; | |
61 | |
62 int entries=-1,dim=-1,quantvals=-1,addmul=-1,sequencep=0; | |
63 FILE *in=NULL; | |
64 char *line,*name; | |
65 long i,j; | |
66 | |
67 memset(&b,0,sizeof(b)); | |
68 memset(&c,0,sizeof(c)); | |
69 | |
70 if(argv[1]==NULL){ | |
71 fprintf(stderr,"Need a lattice description file on the command line.\n"); | |
72 exit(1); | |
73 } | |
74 | |
75 { | |
76 char *ptr; | |
77 char *filename=_ogg_calloc(strlen(argv[1])+4,1); | |
78 | |
79 strcpy(filename,argv[1]); | |
80 in=fopen(filename,"r"); | |
81 if(!in){ | |
82 fprintf(stderr,"Could not open input file %s\n",filename); | |
83 exit(1); | |
84 } | |
85 | |
86 ptr=strrchr(filename,'.'); | |
87 if(ptr){ | |
88 *ptr='\0'; | |
89 name=strdup(filename); | |
90 }else{ | |
91 name=strdup(filename); | |
92 } | |
93 | |
94 } | |
95 | |
96 /* read the description */ | |
97 line=get_line(in); | |
98 if(sscanf(line,"%d %d %d %d",&quantvals,&dim,&addmul,&sequencep)!=4){ | |
99 if(sscanf(line,"%d %d %d",&quantvals,&dim,&addmul)!=3){ | |
100 fprintf(stderr,"Syntax error reading description file (line 1)\n"); | |
101 exit(1); | |
102 } | |
103 } | |
104 entries=pow(quantvals,dim); | |
105 c.dim=dim; | |
106 c.entries=entries; | |
107 c.lengthlist=_ogg_malloc(entries*sizeof(long)); | |
108 c.maptype=1; | |
109 c.q_sequencep=sequencep; | |
110 c.quantlist=_ogg_calloc(quantvals,sizeof(long)); | |
111 | |
112 quantlist=_ogg_malloc(sizeof(double)*c.dim*c.entries); | |
113 hits=_ogg_malloc(c.entries*sizeof(long)); | |
114 for(j=0;j<entries;j++)hits[j]=1; | |
115 for(j=0;j<entries;j++)c.lengthlist[j]=1; | |
116 | |
117 reset_next_value(); | |
118 line=setup_line(in); | |
119 for(j=0;j<quantvals;j++){ | |
120 char *temp; | |
121 if(!line || sscanf(line,"%lf",quantlist+j)!=1){ | |
122 fprintf(stderr,"Ran out of data on line 2 of description file\n"); | |
123 exit(1); | |
124 } | |
125 temp=strchr(line,','); | |
126 if(!temp)temp=strchr(line,' '); | |
127 if(temp)temp++; | |
128 line=temp; | |
129 } | |
130 | |
131 /* gen a real quant list from the more easily human-grokked input */ | |
132 { | |
133 double min=quantlist[0]; | |
134 double mindel=-1; | |
135 int fac=1; | |
136 for(j=1;j<quantvals;j++)if(quantlist[j]<min)min=quantlist[j]; | |
137 for(j=0;j<quantvals;j++) | |
138 for(i=j+1;i<quantvals;i++) | |
139 if(mindel==-1 || fabs(quantlist[j]-quantlist[i])<mindel) | |
140 mindel=fabs(quantlist[j]-quantlist[i]); | |
141 | |
142 j=0; | |
143 while(j<quantvals){ | |
144 for(j=0;j<quantvals;j++){ | |
145 double test=fac*(quantlist[j]-min)/mindel; | |
146 if( fabs(rint(test)-test)>.00001f) break; | |
147 } | |
148 if(fac>100)break; | |
149 if(j<quantvals)fac++; | |
150 } | |
151 | |
152 mindel/=fac; | |
153 fprintf(stderr,"min=%g mindel=%g\n",min,mindel); | |
154 | |
155 c.q_min=_float32_pack(min); | |
156 c.q_delta=_float32_pack(mindel); | |
157 c.q_quant=0; | |
158 | |
159 min=_float32_unpack(c.q_min); | |
160 mindel=_float32_unpack(c.q_delta); | |
161 for(j=0;j<quantvals;j++){ | |
162 c.quantlist[j]=rint((quantlist[j]-min)/mindel); | |
163 if(ilog(c.quantlist[j])>c.q_quant)c.q_quant=ilog(c.quantlist[j]); | |
164 } | |
165 } | |
166 | |
167 /* build the [default] codeword lengths */ | |
168 memset(c.lengthlist,0,sizeof(long)*entries); | |
169 for(i=0;i<entries;i++)hits[i]=1; | |
170 build_tree_from_lengths(entries,hits,c.lengthlist); | |
171 | |
172 /* save the book in C header form */ | |
173 write_codebook(stdout,name,&c); | |
174 fprintf(stderr,"\r " | |
175 "\nDone.\n"); | |
176 exit(0); | |
177 } |