Bringing rc2 (minus the modes it needs) onto mainline.
[platform/upstream/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 XIPHOPHORUS Company http://www.xiph.org/                  *
10
11  ********************************************************************
12
13  function: residue backend 0 partitioner/classifier
14  last mod: $Id: residuesplit.c,v 1.11 2001/08/13 01:37:17 xiphmont Exp $
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   long i,j,part=0;
69   int aux;
70
71   for(i=0;i<=n-subn;i+=subn,part++){
72     float max=0.f;
73     float lentropy=0.f;
74
75     lentropy=_testhack(res+i,subn);
76
77     for(j=0;j<subn;j++)
78       if(fabs(res[i+j])>max)max=fabs(res[i+j]);
79
80     for(j=0;j<parts-1;j++)
81       if(lentropy<=ebound[j] &&
82          max<=mbound[j] &&
83          part<subgrp[j])
84         break;
85     aux=j;
86     
87     fprintf(of,"%d, ",aux);
88     
89     for(j=0;j<subn;j++)
90       fprintf(or[aux],"%g, ",res[j+i]);
91     
92     fprintf(or[aux],"\n");
93   }
94
95   fprintf(of,"\n");
96
97   return(0);
98 }
99
100 static int getline(FILE *in,float *vec,int begin,int n){
101   int i,next=0;
102
103   reset_next_value();
104   if(get_next_value(in,vec))return(0);
105   if(begin){
106     for(i=1;i<begin;i++)
107       get_line_value(in,vec);
108     next=0;
109   }else{
110     next=1;
111   }
112
113   for(i=next;i<n;i++)
114     if(get_line_value(in,vec+i)){
115       fprintf(stderr,"ran out of columns in input data\n");
116       exit(1);
117     }
118   
119   return(1);
120 }
121
122 static void usage(){
123   fprintf(stderr,
124           "usage:\n" 
125           "residuesplit <res> <begin,n,group> <baseout> <ent,peak,sub> [<ent,peak,sub>]...\n"
126           "   where begin,n,group is first scalar, \n"
127           "                          number of scalars of each in line,\n"
128           "                          number of scalars in a group\n"
129           "         ent is the maximum entropy value allowed for membership in a group\n"
130           "         peak is the maximum amplitude value allowed for membership in a group\n"
131           "         subn is the maximum subpartiton number allowed in the group\n"
132                    
133           "eg: residuesplit mask.vqd floor.vqd 0,1024,16 res 0,.5,2 3,1.5,4 \n"
134           "produces resaux.vqd and res_0...n.vqd\n\n");
135   exit(1);
136 }
137
138 int main(int argc, char *argv[]){
139   char *buffer;
140   char *base;
141   int i,parts,begin,n,subn,*subgrp;
142   FILE *res;
143   float *ebound,*mbound,*vec;
144   long c=0;
145   if(argc<5)usage();
146
147   base=strdup(argv[3]);
148   buffer=alloca(strlen(base)+20);
149   {
150     char *pos=strchr(argv[2],',');
151     begin=atoi(argv[2]);
152     if(!pos)
153       usage();
154     else
155       n=atoi(pos+1);
156     pos=strchr(pos+1,',');
157     if(!pos)
158       usage();
159     else
160       subn=atoi(pos+1);
161     if(n/subn*subn != n){
162       fprintf(stderr,"n must be divisible by group\n");
163       exit(1);
164     }
165   }
166
167   /* how many parts?... */
168   parts=argc-3;
169   
170   ebound=_ogg_malloc(sizeof(float)*parts);
171   mbound=_ogg_malloc(sizeof(float)*parts);
172   subgrp=_ogg_malloc(sizeof(int)*parts);
173   
174   for(i=0;i<parts-1;i++){
175     char *pos=strchr(argv[4+i],',');
176     subgrp[i]=0;
177     if(*argv[4+i]==',')
178       ebound[i]=1e50f;
179     else
180       ebound[i]=atof(argv[4+i]);
181
182     if(!pos){
183       mbound[i]=1e50f;
184     }else{
185       if(*(pos+1)==',')
186         mbound[i]=1e50f;
187       else
188         mbound[i]=atof(pos+1);
189       pos=strchr(pos+1,',');
190       
191        if(pos)
192          subgrp[i]=atoi(pos+1);
193        
194     }
195     if(subgrp[i]<=0)subgrp[i]=99999;
196   }
197
198   ebound[i]=1e50f;
199   mbound[i]=1e50f;
200   subgrp[i]=9999999;
201
202   res=fopen(argv[1],"r");
203   if(!res){
204     fprintf(stderr,"Could not open file %s\n",argv[1]);
205     exit(1);
206   }
207
208   or=alloca(parts*sizeof(FILE*));
209   sprintf(buffer,"%saux.vqd",base);
210   of=fopen(buffer,"w");
211   if(!of){
212     fprintf(stderr,"Could not open file %s for writing\n",buffer);
213     exit(1);
214   }
215   for(i=0;i<parts;i++){
216     sprintf(buffer,"%s_%d.vqd",base,i);
217     or[i]=fopen(buffer,"w");
218     if(!or[i]){
219       fprintf(stderr,"Could not open file %s for writing\n",buffer);
220       exit(1);
221     }
222   }
223   
224   vec=_ogg_malloc(sizeof(float)*n);
225   /* get the input line by line and process it */
226   while(!feof(res)){
227     if(getline(res,vec,begin,n))
228       quantaux(vec,n,ebound,mbound,subgrp,parts,subn);
229     c++;
230     if(!(c&0xf)){
231       spinnit("kB so far...",(int)(ftell(res)/1024));
232     }
233   }
234   fclose(res);
235   fclose(of);
236   for(i=0;i<parts;i++)
237     fclose(or[i]);
238   fprintf(stderr,"\rDone                         \n");
239   return(0);
240 }
241
242
243
244