Additional optimizations, rearrangement.
[platform/upstream/libvorbis.git] / vq / latticetune.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: utility main for setting entropy encoding parameters
14            for lattice codebooks
15  last mod: $Id: latticetune.c,v 1.9 2001/06/15 21:15:43 xiphmont Exp $
16
17  ********************************************************************/
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <math.h>
22 #include <string.h>
23 #include <errno.h>
24 #include "bookutil.h"
25
26 static char *strrcmp_i(char *s,char *cmp){
27   return(strncmp(s+strlen(s)-strlen(cmp),cmp,strlen(cmp)));
28 }
29
30 /* This util takes a training-collected file listing codewords used in
31    LSP fitting, then generates new codeword lengths for maximally
32    efficient integer-bits entropy encoding.
33
34    command line:
35    latticetune book.vqh input.vqd [unused_entriesp]
36
37    latticetune produces book.vqh on stdout */
38
39 int main(int argc,char *argv[]){
40   codebook *b;
41   static_codebook *c;
42   long *lengths;
43   long *hits;
44
45   int entries=-1,dim=-1,guard=1;
46   FILE *in=NULL;
47   char *line,*name;
48   long j;
49
50   if(argv[1]==NULL){
51     fprintf(stderr,"Need a lattice codebook on the command line.\n");
52     exit(1);
53   }
54   if(argv[2]==NULL){
55     fprintf(stderr,"Need a codeword data file on the command line.\n");
56     exit(1);
57   }
58   if(argv[3]!=NULL)guard=0;
59
60   {
61     char *ptr;
62     char *filename=strdup(argv[1]);
63
64     b=codebook_load(filename);
65     c=(static_codebook *)(b->c);
66     
67     ptr=strrchr(filename,'.');
68     if(ptr){
69       *ptr='\0';
70       name=strdup(filename);
71     }else{
72       name=strdup(filename);
73     }
74   }
75
76   if(c->maptype!=1){
77     fprintf(stderr,"Provided book is not a latticebook.\n");
78     exit(1);
79   }
80
81   entries=b->entries;
82   dim=b->dim;
83
84   hits=_ogg_malloc(entries*sizeof(long));
85   lengths=_ogg_calloc(entries,sizeof(long));
86   for(j=0;j<entries;j++)hits[j]=guard;
87
88   in=fopen(argv[2],"r");
89   if(!in){
90     fprintf(stderr,"Could not open input file %s\n",argv[2]);
91     exit(1);
92   }
93
94   if(!strrcmp_i(argv[0],"latticetune")){
95     long lines=0;
96     line=setup_line(in);
97     while(line){      
98       long code;
99       lines++;
100       if(!(lines&0xfff))spinnit("codewords so far...",lines);
101       
102       if(sscanf(line,"%ld",&code)==1)
103         hits[code]++;
104
105       line=setup_line(in);
106     }
107   }
108
109   if(!strrcmp_i(argv[0],"res0tune") || !strrcmp_i(argv[0],"res1tune")){
110     long step,adv,max;
111     long lines=0;
112     long cols=-1;
113     float *vec;
114     long interleave=1;
115     if(!strrcmp_i(argv[0],"res1tune"))
116       interleave=0;
117
118     line=setup_line(in);
119     while(line){
120       int code;
121       if(!(lines&0xfff))spinnit("codewords so far...",lines);
122
123       if(cols==-1){
124         char *temp=line;
125         while(*temp==' ')temp++;
126         for(cols=0;*temp;cols++){
127           while(*temp>32)temp++;
128           while(*temp==' ')temp++;
129         }
130         vec=alloca(sizeof(float)*cols);
131         if(interleave){
132           step=cols/dim;
133           adv=1;
134           max=step;
135         }else{
136           step=1;
137           adv=dim;
138           max=cols-dim+1;
139         }
140       }
141       
142       for(j=0;j<cols;j++)
143         if(get_line_value(in,vec+j)){
144           fprintf(stderr,"Too few columns on line %ld in data file\n",lines);
145           exit(1);
146         }
147       
148       for(j=0;j<max;j+=adv){
149         lines++;
150         code=_best(b,vec+j,step);
151         hits[code]++;
152       }
153
154       line=setup_line(in);
155     }
156   }
157
158   fclose(in);
159
160   /* build the codeword lengths */
161   build_tree_from_lengths0(entries,hits,lengths);
162
163   c->lengthlist=lengths;
164   write_codebook(stdout,name,c); 
165
166   {
167     long bins=_book_maptype1_quantvals(c);
168     long i,k,base=c->lengthlist[0];
169     for(i=0;i<entries;i++)
170       if(c->lengthlist[i]>base)base=c->lengthlist[i];
171     
172     for(j=0;j<entries;j++){
173       if(c->lengthlist[j]){
174         int indexdiv=1;
175         fprintf(stderr,"%4ld: ",j);
176         for(k=0;k<c->dim;k++){      
177           int index= (j/indexdiv)%bins;
178           fprintf(stderr,"%+3.1f,", c->quantlist[index]*_float32_unpack(c->q_delta)+
179                  _float32_unpack(c->q_min));
180           indexdiv*=bins;
181         }
182         fprintf(stderr,"\t|",(1<<(base-c->lengthlist[j])));
183         for(k=0;k<base-c->lengthlist[j];k++)fprintf(stderr,"*");
184         fprintf(stderr,"\n");
185       }
186     }
187   }
188   
189   fprintf(stderr,"\r                                                     "
190           "\nDone.\n");
191   exit(0);
192 }