Update tizen 2.0 beta source
[external/libvorbis.git] / vq / build.c
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 training sets
14  last mod: $Id: build.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 #include "vqgen.h"
26 #include "vqsplit.h"
27
28 static char *linebuffer=NULL;
29 static int  lbufsize=0;
30 static char *rline(FILE *in,FILE *out){
31   long sofar=0;
32   if(feof(in))return NULL;
33
34   while(1){
35     int gotline=0;
36
37     while(!gotline){
38       if(sofar>=lbufsize){
39         if(!lbufsize){        
40           lbufsize=1024;
41           linebuffer=_ogg_malloc(lbufsize);
42         }else{
43           lbufsize*=2;
44           linebuffer=_ogg_realloc(linebuffer,lbufsize);
45         }
46       }
47       {
48         long c=fgetc(in);
49         switch(c){
50         case '\n':
51         case EOF:
52           gotline=1;
53           break;
54         default:
55           linebuffer[sofar++]=c;
56           linebuffer[sofar]='\0';
57           break;
58         }
59       }
60     }
61     
62     if(linebuffer[0]=='#'){
63       sofar=0;
64     }else{
65       return(linebuffer);
66     }
67   }
68 }
69
70 /* command line:
71    buildvq file
72 */
73
74 int main(int argc,char *argv[]){
75   vqgen v;
76   static_codebook c;
77   codebook b;
78   quant_meta q;
79
80   long *quantlist=NULL;
81   int entries=-1,dim=-1,aux=-1;
82   FILE *out=NULL;
83   FILE *in=NULL;
84   char *line,*name;
85   long i,j,k;
86
87   b.c=&c;
88
89   if(argv[1]==NULL){
90     fprintf(stderr,"Need a trained data set on the command line.\n");
91     exit(1);
92   }
93
94   {
95     char *ptr;
96     char *filename=strdup(argv[1]);
97
98     in=fopen(filename,"r");
99     if(!in){
100       fprintf(stderr,"Could not open input file %s\n",filename);
101       exit(1);
102     }
103     
104     ptr=strrchr(filename,'-');
105     if(ptr){
106       *ptr='\0';
107       name=strdup(filename);
108       sprintf(ptr,".vqh");
109     }else{
110       name=strdup(filename);
111       strcat(filename,".vqh");
112     }
113
114     out=fopen(filename,"w");
115     if(out==NULL){
116       fprintf(stderr,"Unable to open %s for writing\n",filename);
117       exit(1);
118     }
119   }
120
121   /* suck in the trained book */
122
123   /* read book type, but it doesn't matter */
124   line=rline(in,out);
125   
126   line=rline(in,out);
127   if(sscanf(line,"%d %d %d",&entries,&dim,&aux)!=3){
128     fprintf(stderr,"Syntax error reading book file\n");
129     exit(1);
130   }
131   
132   /* just use it to allocate mem */
133   vqgen_init(&v,dim,0,entries,0.f,NULL,NULL,0);
134   
135   /* quant */
136   line=rline(in,out);
137   if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta,
138             &q.quant,&q.sequencep)!=4){
139     fprintf(stderr,"Syntax error reading book file\n");
140     exit(1);
141   }
142   
143   /* quantized entries */
144   /* save quant data; we don't want to requantize later as our method
145      is currently imperfect wrt repeated application */
146   i=0;
147   quantlist=_ogg_malloc(sizeof(long)*v.elements*v.entries);
148   for(j=0;j<entries;j++){
149     float a;
150     for(k=0;k<dim;k++){
151       line=rline(in,out);
152       sscanf(line,"%f",&a);
153       v.entrylist[i]=a;
154       quantlist[i++]=rint(a);
155     }
156   }    
157   
158   /* ignore bias */
159   for(j=0;j<entries;j++)line=rline(in,out);
160   free(v.bias);
161   v.bias=NULL;
162   
163   /* training points */
164   {
165     float *b=alloca(sizeof(float)*(dim+aux));
166     i=0;
167     v.entries=0; /* hack to avoid reseeding */
168     while(1){
169       for(k=0;k<dim+aux;k++){
170         line=rline(in,out);
171         if(!line)break;
172         sscanf(line,"%f",b+k);
173       }
174       if(feof(in))break;
175       vqgen_addpoint(&v,b,NULL);
176     }
177     v.entries=entries;
178   }
179   
180   fclose(in);
181   vqgen_unquantize(&v,&q);
182
183   /* build the book */
184   vqsp_book(&v,&b,quantlist);
185   c.q_min=q.min;
186   c.q_delta=q.delta;
187   c.q_quant=q.quant;
188   c.q_sequencep=q.sequencep;
189
190   /* save the book in C header form */
191   write_codebook(out,name,b.c);
192
193   fclose(out);
194   exit(0);
195 }