Fixes for codebook geenration (keeping up to date)
[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 SOURCE IS GOVERNED BY *
5  * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH    *
6  * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.        *
7  *                                                                  *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
9  * by Monty <monty@xiph.org> and the XIPHOPHORUS Company            *
10  * http://www.xiph.org/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: residue backend 0 partitioner/classifier
15  last mod: $Id: residuesplit.c,v 1.7 2000/11/08 03:23:23 xiphmont Exp $
16
17  ********************************************************************/
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <math.h>
22 #include <stdio.h>
23 #include "bookutil.h"
24
25 /* does not guard against invalid settings; eg, a subn of 16 and a
26    subgroup request of 32.  Max subn of 128 */
27 static void _testhack(float *vec,int n,float *entropy){
28   int i,j=0;
29   float max=0.;
30   float temp[128];
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   while(1){
42     entropy[j]=max;
43     n>>=1;
44     j++;
45
46     if(n<=0)break;
47     for(i=0;i<n;i++){
48       temp[i]+=temp[i+n];
49     }
50     max=0.;
51     for(i=0;i<n;i++)
52       if(temp[i]>max)max=temp[i];
53   }
54 }
55
56 static FILE *of;
57 static FILE **or;
58
59 /* we evaluate the the entropy measure for each interleaved subgroup */
60 /* This is currently a bit specific to/hardwired for mapping 0; things
61    will need to change in the future when we get real multichannel
62    mappings */
63 int quantaux(float *res,int n,float *ebound,float *mbound,int *subgrp,int parts, int subn){
64   long i,j;
65   float entropy[8];
66   int aux;
67
68   for(i=0;i<=n-subn;i+=subn){
69     float max=0.;
70
71     _testhack(res+i,subn,entropy);
72     for(j=0;j<subn;j++)
73       if(fabs(res[i+j])>max)max=fabs(res[i+j]);
74
75     for(j=0;j<parts-1;j++)
76       if(entropy[subgrp[j]]<=ebound[j] &&
77          max<=mbound[j])
78         break;
79     aux=j;
80     
81     fprintf(of,"%d, ",aux);
82     
83     for(j=0;j<subn;j++)
84       fprintf(or[aux],"%g, ",res[j+i]);
85     
86     fprintf(or[aux],"\n");
87   }
88
89   fprintf(of,"\n");
90
91   return(0);
92 }
93
94 static int getline(FILE *in,float *vec,int begin,int n){
95   int i,next=0;
96
97   reset_next_value();
98   if(get_next_value(in,vec))return(0);
99   if(begin){
100     for(i=1;i<begin;i++)
101       get_line_value(in,vec);
102     next=0;
103   }else{
104     next=1;
105   }
106
107   for(i=next;i<n;i++)
108     if(get_line_value(in,vec+i)){
109       fprintf(stderr,"ran out of columns in input data\n");
110       exit(1);
111     }
112   
113   return(1);
114 }
115
116 static void usage(){
117   fprintf(stderr,
118           "usage:\n" 
119           "residuesplit <res> <begin,n,group> <baseout> <ent,peak,sub> [<ent,peak,sub>]...\n"
120           "   where begin,n,group is first scalar, \n"
121           "                          number of scalars of each in line,\n"
122           "                          number of scalars in a group\n"
123           "         ent is the maximum entropy value allowed for membership in a group\n"
124           "         peak is the maximum amplitude value allowed for membership in a group\n"
125           "         subn is the maximum entropy value allowed for membership in a group\n"
126                    
127           "eg: residuesplit mask.vqd floor.vqd 0,1024,16 res 0,.5,16 3,1.5,8 \n"
128           "produces resaux.vqd and res_0...n.vqd\n\n");
129   exit(1);
130 }
131
132 int main(int argc, char *argv[]){
133   char *buffer;
134   char *base;
135   int i,parts,begin,n,subn,*subgrp;
136   FILE *res;
137   float *ebound,*mbound,*vec;
138   long c=0;
139   if(argc<5)usage();
140
141   base=strdup(argv[3]);
142   buffer=alloca(strlen(base)+20);
143   {
144     char *pos=strchr(argv[2],',');
145     begin=atoi(argv[2]);
146     if(!pos)
147       usage();
148     else
149       n=atoi(pos+1);
150     pos=strchr(pos+1,',');
151     if(!pos)
152       usage();
153     else
154       subn=atoi(pos+1);
155     if(n/subn*subn != n){
156       fprintf(stderr,"n must be divisible by group\n");
157       exit(1);
158     }
159   }
160
161   /* how many parts?... */
162   parts=argc-3;
163   
164   ebound=_ogg_malloc(sizeof(float)*parts);
165   mbound=_ogg_malloc(sizeof(float)*parts);
166   subgrp=_ogg_malloc(sizeof(int)*parts);
167   
168   for(i=0;i<parts-1;i++){
169     char *pos=strchr(argv[4+i],',');
170     if(*argv[4+i]==',')
171       ebound[i]=1e50;
172     else
173       ebound[i]=atof(argv[4+i]);
174
175     if(!pos){
176       mbound[i]=1e50;
177       subgrp[i]=_ilog(subn)-1;
178      }else{
179        if(*(pos+1)==',')
180          mbound[i]=1e50;
181        else
182          mbound[i]=atof(pos+1);
183        pos=strchr(pos+1,',');
184        
185        if(!pos){
186          subgrp[i]=_ilog(subn)-1;
187        }else{
188          subgrp[i]=_ilog(atoi(pos+1))-1;
189        }
190      }
191   }
192
193   ebound[i]=1e50;
194   mbound[i]=1e50;
195   subgrp[i]=_ilog(subn)-1;
196
197   res=fopen(argv[1],"r");
198   if(!res){
199     fprintf(stderr,"Could not open file %s\n",argv[1]);
200     exit(1);
201   }
202
203   or=alloca(parts*sizeof(FILE*));
204   sprintf(buffer,"%saux.vqd",base);
205   of=fopen(buffer,"w");
206   if(!of){
207     fprintf(stderr,"Could not open file %s for writing\n",buffer);
208     exit(1);
209   }
210   for(i=0;i<parts;i++){
211     sprintf(buffer,"%s_%d.vqd",base,i);
212     or[i]=fopen(buffer,"w");
213     if(!or[i]){
214       fprintf(stderr,"Could not open file %s for writing\n",buffer);
215       exit(1);
216     }
217   }
218   
219   vec=_ogg_malloc(sizeof(float)*n);
220   /* get the input line by line and process it */
221   while(!feof(res)){
222     if(getline(res,vec,begin,n))
223       quantaux(vec,n,ebound,mbound,subgrp,parts,subn);
224     c++;
225     if(!(c&0xf)){
226       spinnit("kB so far...",(int)(ftell(res)/1024));
227     }
228   }
229   fclose(res);
230   fclose(of);
231   for(i=0;i<parts;i++)
232     fclose(or[i]);
233   fprintf(stderr,"\rDone                         \n");
234   return(0);
235 }
236
237
238
239