1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
9 * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: utility main for building codebooks from training sets
15 last mod: $Id: build.c,v 1.12 2000/02/16 16:18:34 xiphmont Exp $
17 ********************************************************************/
24 #include "vorbis/codebook.h"
29 static char *linebuffer=NULL;
30 static int lbufsize=0;
31 static char *rline(FILE *in,FILE *out){
33 if(feof(in))return NULL;
42 linebuffer=malloc(lbufsize);
45 linebuffer=realloc(linebuffer,lbufsize);
56 linebuffer[sofar++]=c;
57 linebuffer[sofar]='\0';
63 if(linebuffer[0]=='#'){
75 int main(int argc,char *argv[]){
82 int entries=-1,dim=-1,aux=-1;
91 fprintf(stderr,"Need a trained data set on the command line.\n");
97 char *filename=strdup(argv[1]);
99 in=fopen(filename,"r");
101 fprintf(stderr,"Could not open input file %s\n",filename);
105 ptr=strrchr(filename,'-');
108 name=strdup(filename);
111 name=strdup(filename);
112 strcat(filename,".vqh");
115 out=fopen(filename,"w");
117 fprintf(stderr,"Unable to open %s for writing\n",filename);
122 /* suck in the trained book */
124 /* read book type, but it doesn't matter */
128 if(sscanf(line,"%d %d %d",&entries,&dim,&aux)!=3){
129 fprintf(stderr,"Syntax error reading book file\n");
133 /* just use it to allocate mem */
134 vqgen_init(&v,dim,0,entries,0.,NULL,NULL);
138 if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta,
139 &q.quant,&q.sequencep)!=4){
140 fprintf(stderr,"Syntax error reading book file\n");
144 /* quantized entries */
145 /* save quant data; we don't want to requantize later as our method
146 is currently imperfect wrt repeated application */
148 quantlist=malloc(sizeof(long)*v.elements*v.entries);
149 for(j=0;j<entries;j++){
153 sscanf(line,"%lf",&a);
155 quantlist[i++]=rint(a);
160 for(j=0;j<entries;j++)line=rline(in,out);
164 /* training points */
166 double *b=alloca(sizeof(double)*(dim+aux));
168 v.entries=0; /* hack to avoid reseeding */
170 for(k=0;k<dim+aux;k++){
173 sscanf(line,"%lf",b+k);
176 vqgen_addpoint(&v,b,NULL);
182 vqgen_unquantize(&v,&q);
185 vqsp_book(&v,&b,quantlist);
187 /* save the book in C header form */
189 "/********************************************************************\n"
191 " * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *\n"
192 " * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *\n"
193 " * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *\n"
194 " * PLEASE READ THESE TERMS DISTRIBUTING. *\n"
196 " * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *\n"
197 " * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *\n"
198 " * http://www.xiph.org/ *\n"
200 " ********************************************************************\n"
202 " function: static codebook autogenerated by vq/vqbuild\n"
204 " ********************************************************************/\n\n");
206 fprintf(out,"#ifndef _V_%s_VQH_\n#define _V_%s_VQH_\n",name,name);
207 fprintf(out,"#include \"vorbis/codebook.h\"\n\n");
209 /* first, the static vectors, then the book structure to tie it together. */
211 fprintf(out,"static long _vq_quantlist_%s[] = {\n",name);
213 for(j=0;j<c.entries;j++){
216 fprintf(out,"%5ld, ",c.quantlist[i++]);
219 fprintf(out,"};\n\n");
222 fprintf(out,"static long _vq_lengthlist_%s[] = {\n",name);
223 for(j=0;j<c.entries;){
225 for(k=0;k<16 && j<c.entries;k++,j++)
226 fprintf(out,"%2ld,",c.lengthlist[j]);
229 fprintf(out,"};\n\n");
232 fprintf(out,"static long _vq_ptr0_%s[] = {\n",name);
233 for(j=0;j<c.encode_tree->aux;){
235 for(k=0;k<8 && j<c.encode_tree->aux;k++,j++)
236 fprintf(out,"%6ld,",c.encode_tree->ptr0[j]);
239 fprintf(out,"};\n\n");
242 fprintf(out,"static long _vq_ptr1_%s[] = {\n",name);
243 for(j=0;j<c.encode_tree->aux;){
245 for(k=0;k<8 && j<c.encode_tree->aux;k++,j++)
246 fprintf(out,"%6ld,",c.encode_tree->ptr1[j]);
249 fprintf(out,"};\n\n");
252 fprintf(out,"static long _vq_p_%s[] = {\n",name);
253 for(j=0;j<c.encode_tree->aux;){
255 for(k=0;k<8 && j<c.encode_tree->aux;k++,j++)
256 fprintf(out,"%6ld,",c.encode_tree->p[j]*c.dim);
259 fprintf(out,"};\n\n");
262 fprintf(out,"static long _vq_q_%s[] = {\n",name);
263 for(j=0;j<c.encode_tree->aux;){
265 for(k=0;k<8 && j<c.encode_tree->aux;k++,j++)
266 fprintf(out,"%6ld,",c.encode_tree->q[j]*c.dim);
269 fprintf(out,"};\n\n");
271 /* tie it all together */
273 fprintf(out,"static encode_aux _vq_aux_%s = {\n",name);
274 fprintf(out,"\t_vq_ptr0_%s,\n",name);
275 fprintf(out,"\t_vq_ptr1_%s,\n",name);
276 fprintf(out,"\t_vq_p_%s,\n",name);
277 fprintf(out,"\t_vq_q_%s,\n",name);
278 fprintf(out,"\t%ld, %ld\n};\n\n",c.encode_tree->aux,c.encode_tree->aux);
280 fprintf(out,"static static_codebook _vq_book_%s = {\n",name);
281 fprintf(out,"\t%ld, %ld, %ld, %ld, %d, %d,\n",
282 c.dim,c.entries,q.min,q.delta,q.quant,q.sequencep);
283 fprintf(out,"\t_vq_quantlist_%s,\n",name);
284 fprintf(out,"\t_vq_lengthlist_%s,\n",name);
285 fprintf(out,"\t&_vq_aux_%s,\n",name);
286 fprintf(out,"};\n\n");
288 fprintf(out,"\n#endif\n");