Update tizen 2.0 beta source
[external/libvorbis.git] / vq / residuesplit.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: residue backend 0 partitioner/classifier
14  last mod: $Id: residuesplit.c 16037 2009-05-26 21:10:58Z xiphmont $
15
16  ********************************************************************/
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include <math.h>
21 #include <stdio.h>
22 #include "bookutil.h"
23
24 /* does not guard against invalid settings; eg, a subn of 16 and a
25    subgroup request of 32.  Max subn of 128 */
26 static float _testhack(float *vec,int n){
27   int i,j=0;
28   float max=0.f;
29   float temp[128];
30   float entropy=0.;
31
32   /* setup */
33   for(i=0;i<n;i++)temp[i]=fabs(vec[i]);
34
35   /* handle case subgrp==1 outside */
36   for(i=0;i<n;i++)
37     if(temp[i]>max)max=temp[i];
38
39   for(i=0;i<n;i++)temp[i]=rint(temp[i]);
40
41   for(i=0;i<n;i++)
42     entropy+=temp[i];
43   return entropy;
44
45   /*while(1){
46     entropy[j]=max;
47     n>>=1;
48     j++;
49
50     if(n<=0)break;
51     for(i=0;i<n;i++){
52       temp[i]+=temp[i+n];
53     }
54     max=0.f;
55     for(i=0;i<n;i++)
56       if(temp[i]>max)max=temp[i];
57       }*/
58 }
59
60 static FILE *of;
61 static FILE **or;
62
63 /* we evaluate the the entropy measure for each interleaved subgroup */
64 /* This is currently a bit specific to/hardwired for mapping 0; things
65    will need to change in the future when we get real multichannel
66    mappings */
67 int quantaux(float *res,int n,float *ebound,float *mbound,int *subgrp,int parts, int subn, 
68              int *class){
69   long i,j,part=0;
70   int aux;
71
72   for(i=0;i<=n-subn;i+=subn,part++){
73     float max=0.f;
74     float lentropy=0.f;
75
76     lentropy=_testhack(res+i,subn);
77
78     for(j=0;j<subn;j++)
79       if(fabs(res[i+j])>max)max=fabs(res[i+j]);
80
81     for(j=0;j<parts-1;j++)
82       if(lentropy<=ebound[j] &&
83          max<=mbound[j] &&
84          part<subgrp[j])
85         break;
86     class[part]=aux=j;
87     
88     fprintf(of,"%d, ",aux);
89   }    
90   fprintf(of,"\n");
91
92   return(0);
93 }
94
95 int quantwrite(float *res,int n,int subn, int *class,int offset){
96   long i,j,part=0;
97   int aux;
98
99   for(i=0;i<=n-subn;i+=subn,part++){
100     aux=class[part];
101     
102     for(j=0;j<subn;j++)
103       fprintf(or[aux+offset],"%g, ",res[j+i]);
104     
105     fprintf(or[aux+offset],"\n");
106   }
107
108   return(0);
109 }
110
111 static int getline(FILE *in,float *vec,int begin,int n){
112   int i,next=0;
113
114   reset_next_value();
115   if(get_next_value(in,vec))return(0);
116   if(begin){
117     for(i=1;i<begin;i++)
118       get_line_value(in,vec);
119     next=0;
120   }else{
121     next=1;
122   }
123
124   for(i=next;i<n;i++)
125     if(get_line_value(in,vec+i)){
126       fprintf(stderr,"ran out of columns in input data\n");
127       exit(1);
128     }
129   
130   return(1);
131 }
132
133 static void usage(){
134   fprintf(stderr,
135           "usage:\n" 
136           "residuesplit <res> [<res>] <begin,n,group> <baseout> <ent,peak,sub> [<ent,peak,sub>]...\n"
137           "   where begin,n,group is first scalar, \n"
138           "                          number of scalars of each in line,\n"
139           "                          number of scalars in a group\n"
140           "         ent is the maximum entropy value allowed for membership in a group\n"
141           "         peak is the maximum amplitude value allowed for membership in a group\n"
142           "         subn is the maximum subpartiton number allowed in the group\n\n");
143   exit(1);
144 }
145
146 int main(int argc, char *argv[]){
147   char *buffer;
148   char *base;
149   int i,j,parts,begin,n,subn,*subgrp,*class;
150   FILE **res;
151   int resfiles=0;
152   float *ebound,*mbound,*vec;
153   long c=0;
154   if(argc<5)usage();
155
156   /* count the res file names, open the files */
157   while(!strcmp(argv[resfiles+1]+strlen(argv[resfiles+1])-4,".vqd"))
158     resfiles++;
159   if(resfiles<1)usage();
160
161   res=alloca(sizeof(*res)*resfiles);
162   for(i=0;i<resfiles;i++){
163     res[i]=fopen(argv[i+1],"r");
164     if(!(res+i)){
165       fprintf(stderr,"Could not open file %s\n",argv[1+i]);
166       exit(1);
167     }
168   }
169
170   base=strdup(argv[2+resfiles]);
171   buffer=alloca(strlen(base)+20);
172   {
173     char *pos=strchr(argv[1+resfiles],',');
174     begin=atoi(argv[1+resfiles]);
175     if(!pos)
176       usage();
177     else
178       n=atoi(pos+1);
179     pos=strchr(pos+1,',');
180     if(!pos)
181       usage();
182     else
183       subn=atoi(pos+1);
184     if(n/subn*subn != n){
185       fprintf(stderr,"n must be divisible by group\n");
186       exit(1);
187     }
188   }
189
190   /* how many parts?... */
191   parts=argc-resfiles-2;
192   
193   ebound=_ogg_malloc(sizeof(float)*parts);
194   mbound=_ogg_malloc(sizeof(float)*parts);
195   subgrp=_ogg_malloc(sizeof(int)*parts);
196   
197   for(i=0;i<parts-1;i++){
198     char *pos=strchr(argv[3+i+resfiles],',');
199     subgrp[i]=0;
200     if(*argv[3+i+resfiles]==',')
201       ebound[i]=1e50f;
202     else
203       ebound[i]=atof(argv[3+i+resfiles]);
204
205     if(!pos){
206       mbound[i]=1e50f;
207     }else{
208       if(*(pos+1)==',')
209         mbound[i]=1e50f;
210       else
211         mbound[i]=atof(pos+1);
212       pos=strchr(pos+1,',');
213       
214        if(pos)
215          subgrp[i]=atoi(pos+1);
216        
217     }
218     if(subgrp[i]<=0)subgrp[i]=99999;
219   }
220
221   ebound[i]=1e50f;
222   mbound[i]=1e50f;
223   subgrp[i]=9999999;
224
225   or=alloca(parts*resfiles*sizeof(FILE*));
226   sprintf(buffer,"%saux.vqd",base);
227   of=fopen(buffer,"w");
228   if(!of){
229     fprintf(stderr,"Could not open file %s for writing\n",buffer);
230     exit(1);
231   }
232
233   for(j=0;j<resfiles;j++){
234     for(i=0;i<parts;i++){
235       sprintf(buffer,"%s_%d%c.vqd",base,i,j+65);
236       or[i+j*parts]=fopen(buffer,"w");
237       if(!or[i+j*parts]){
238         fprintf(stderr,"Could not open file %s for writing\n",buffer);
239         exit(1);
240       }
241     }
242   }
243   
244   vec=_ogg_malloc(sizeof(float)*n);
245   class=_ogg_malloc(sizeof(float)*n);
246   /* get the input line by line and process it */
247   while(1){
248     if(getline(res[0],vec,begin,n)){
249       quantaux(vec,n,ebound,mbound,subgrp,parts,subn,class);
250       quantwrite(vec,n,subn,class,0);
251
252       for(i=1;i<resfiles;i++){
253         if(getline(res[i],vec,begin,n)){
254           quantwrite(vec,n,subn,class,parts*i);
255         }else{
256           fprintf(stderr,"Getline loss of sync (%d).\n\n",i);
257           exit(1);
258         }
259       }
260     }else{
261       if(feof(res[0]))break;
262       fprintf(stderr,"Getline loss of sync (0).\n\n");
263       exit(1);
264     }
265     
266     c++;
267     if(!(c&0xf)){
268       spinnit("kB so far...",(int)(ftell(res[0])/1024));
269     }
270   }
271   for(i=0;i<resfiles;i++)
272     fclose(res[i]);
273   fclose(of);
274   for(i=0;i<parts*resfiles;i++)
275     fclose(or[i]);
276   fprintf(stderr,"\rDone                         \n");
277   return(0);
278 }
279
280
281
282