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.8 2000/01/05 10:14:54 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[]){
81 int entries=-1,dim=-1,aux=-1;
88 fprintf(stderr,"Need a trained data set on the command line.\n");
94 char *filename=strdup(argv[1]);
96 in=fopen(filename,"r");
98 fprintf(stderr,"Could not open input file %s\n",filename);
102 ptr=strrchr(filename,'-');
105 name=strdup(filename);
108 name=strdup(filename);
109 strcat(filename,".vqh");
112 out=fopen(filename,"w");
114 fprintf(stderr,"Unable to open %s for writing\n",filename);
119 /* suck in the trained book */
121 /* read book type, but it doesn't matter */
125 if(sscanf(line,"%d %d %d",&entries,&dim,&aux)!=3){
126 fprintf(stderr,"Syntax error reading book file\n");
130 /* just use it to allocate mem */
131 vqgen_init(&v,dim,0,entries,NULL,NULL);
135 if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta,
136 &q.quant,&q.sequencep)!=4){
137 fprintf(stderr,"Syntax error reading book file\n");
141 /* quantized entries */
142 /* save quant data; we don't want to requantize later as our method
143 is currently imperfect wrt repeated application */
145 quantlist=malloc(sizeof(long)*v.elements*v.entries);
146 for(j=0;j<entries;j++){
150 sscanf(line,"%lf",&a);
152 quantlist[i++]=rint(a);
157 for(j=0;j<entries;j++)line=rline(in,out);
161 /* training points */
163 double *b=alloca(sizeof(double)*(dim+aux));
165 v.entries=0; /* hack to avoid reseeding */
167 for(k=0;k<dim+aux;k++){
170 sscanf(line,"%lf",b+k);
173 vqgen_addpoint(&v,b,NULL);
179 vqgen_unquantize(&v,&q);
182 vqsp_book(&v,&b,quantlist);
184 /* save the book in C header form */
186 "/********************************************************************\n"
188 " * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *\n"
189 " * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *\n"
190 " * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *\n"
191 " * PLEASE READ THESE TERMS DISTRIBUTING. *\n"
193 " * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *\n"
194 " * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *\n"
195 " * http://www.xiph.org/ *\n"
197 " ********************************************************************\n"
199 " function: static codebook autogenerated by vq/vqbuild\n"
201 " ********************************************************************/\n\n");
203 fprintf(out,"#ifndef _V_%s_VQH_\n#define _V_%s_VQH_\n",name,name);
204 fprintf(out,"#include \"vorbis/codebook.h\"\n\n");
206 /* first, the static vectors, then the book structure to tie it together. */
208 fprintf(out,"static long _vq_quantlist_%s[] = {\n",name);
210 for(j=0;j<entries;j++){
213 fprintf(out,"%5ld, ",b.quantlist[i++]);
216 fprintf(out,"};\n\n");
219 fprintf(out,"static long _vq_codelist_%s[] = {\n",name);
222 for(k=0;k<8 && j<entries;k++,j++)
223 fprintf(out,"%ld,",b.codelist[j]);
226 fprintf(out,"};\n\n");
229 fprintf(out,"static long _vq_lengthlist_%s[] = {\n",name);
232 for(k=0;k<16 && j<entries;k++,j++)
233 fprintf(out,"%2ld,",b.lengthlist[j]);
236 fprintf(out,"};\n\n");
239 fprintf(out,"static long _vq_ptr0_%s[] = {\n",name);
240 for(j=0;j<b.encode_tree->aux;){
242 for(k=0;k<8 && j<b.encode_tree->aux;k++,j++)
243 fprintf(out,"%6ld,",b.encode_tree->ptr0[j]);
246 fprintf(out,"};\n\n");
249 fprintf(out,"static long _vq_ptr1_%s[] = {\n",name);
250 for(j=0;j<b.encode_tree->aux;){
252 for(k=0;k<8 && j<b.encode_tree->aux;k++,j++)
253 fprintf(out,"%6ld,",b.encode_tree->ptr1[j]);
256 fprintf(out,"};\n\n");
259 fprintf(out,"static long _vq_p_%s[] = {\n",name);
260 for(j=0;j<b.encode_tree->aux;){
262 for(k=0;k<8 && j<b.encode_tree->aux;k++,j++)
263 fprintf(out,"%6ld,",b.encode_tree->p[j]);
266 fprintf(out,"};\n\n");
269 fprintf(out,"static long _vq_q_%s[] = {\n",name);
270 for(j=0;j<b.encode_tree->aux;){
272 for(k=0;k<8 && j<b.encode_tree->aux;k++,j++)
273 fprintf(out,"%6ld,",b.encode_tree->q[j]);
276 fprintf(out,"};\n\n");
278 /* tie it all together */
280 fprintf(out,"static encode_aux _vq_aux_%s = {\n",name);
281 fprintf(out,"\t_vq_ptr0_%s,\n",name);
282 fprintf(out,"\t_vq_ptr1_%s,\n",name);
283 fprintf(out,"\t0,\n");
284 fprintf(out,"\t0,\n");
285 fprintf(out,"\t_vq_p_%s,\n",name);
286 fprintf(out,"\t_vq_q_%s,\n",name);
287 fprintf(out,"\t%ld, %ld\n};\n\n",b.encode_tree->aux,b.encode_tree->aux);
289 fprintf(out,"static codebook _vq_book_%s = {\n",name);
290 fprintf(out,"\t%ld, %ld, %ld, %ld, %d, %d,\n",
291 b.dim,b.entries,q.min,q.delta,q.quant,q.sequencep);
292 fprintf(out,"\t0,\n"); /* valuelist */
293 fprintf(out,"\t_vq_quantlist_%s,\n",name);
294 fprintf(out,"\t_vq_codelist_%s,\n",name);
295 fprintf(out,"\t_vq_lengthlist_%s,\n",name);
296 fprintf(out,"\t&_vq_aux_%s,\n",name);
297 fprintf(out,"\t0\n");
298 fprintf(out,"};\n\n");
300 fprintf(out,"\n#endif\n");