Home | History | Annotate | Download | only in vq
      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 setting entropy encoding parameters
     14            for lattice codebooks
     15  last mod: $Id: latticetune.c 16037 2009-05-26 21:10:58Z xiphmont $
     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 int 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   /* now we simply count already collated by-entry data */
    110   if(!strrcmp_i(argv[0],"res0tune") || !strrcmp_i(argv[0],"res1tune")){
    111 
    112     line=setup_line(in);
    113     while(line){
    114 
    115       /* code:hits\n */
    116       /* likely to have multiple listing for each code entry; must
    117          accumulate */
    118 
    119       char *pos=strchr(line,':');
    120       if(pos){
    121         long code=atol(line);
    122         long val=atol(pos+1);
    123         hits[code]+=val;
    124       }
    125 
    126       line=setup_line(in);
    127     }
    128   }
    129 
    130   fclose(in);
    131 
    132   /* build the codeword lengths */
    133   build_tree_from_lengths0(entries,hits,lengths);
    134 
    135   c->lengthlist=lengths;
    136   write_codebook(stdout,name,c);
    137 
    138   {
    139     long bins=_book_maptype1_quantvals(c);
    140     long i,k,base=c->lengthlist[0];
    141     for(i=0;i<entries;i++)
    142       if(c->lengthlist[i]>base)base=c->lengthlist[i];
    143 
    144     for(j=0;j<entries;j++){
    145       if(c->lengthlist[j]){
    146         int indexdiv=1;
    147         fprintf(stderr,"%4ld: ",j);
    148         for(k=0;k<c->dim;k++){
    149           int index= (j/indexdiv)%bins;
    150           fprintf(stderr,"%+3.1f,", c->quantlist[index]*_float32_unpack(c->q_delta)+
    151                  _float32_unpack(c->q_min));
    152           indexdiv*=bins;
    153         }
    154         fprintf(stderr,"\t|");
    155         for(k=0;k<base-c->lengthlist[j];k++)fprintf(stderr,"*");
    156         fprintf(stderr,"\n");
    157       }
    158     }
    159   }
    160 
    161   fprintf(stderr,"\r                                                     "
    162           "\nDone.\n");
    163   exit(0);
    164 }
    165