int main(int argc,char *argv[]){
  FILE *in;
  long lines=0;
  float min;
  float max;
  long bins=-1;
  int flag=0;
  long *countarray;
  long total=0;
  char *line;

  if(argv[1]==NULL){
    fprintf(stderr,"Usage: distribution {data.vqd [bins]| book.vqh} \n\n");
    exit(1);
  }
  if(argv[2]!=NULL)
    bins=atoi(argv[2])-1;

  in=fopen(argv[1],"r");
  if(!in){
    fprintf(stderr,"Could not open input file %s\n",argv[1]);
    exit(1);
  }

  if(strrchr(argv[1],'.') && strcmp(strrchr(argv[1],'.'),".vqh")==0){
    /* load/decode a book */

    codebook *b=codebook_load(argv[1]);
    static_codebook *c=(static_codebook *)(b->c);
    float delta;
    int i;
    fclose(in);

    switch(c->maptype){
    case 0:
      printf("entropy codebook only; no mappings\n");
      exit(0);
      break;
    case 1:
      bins=_book_maptype1_quantvals(c);
      break;
    case 2:
      bins=c->entries*c->dim;
      break;
    }

    max=min=_float32_unpack(c->q_min);
    delta=_float32_unpack(c->q_delta);

    for(i=0;i<bins;i++){
      float val=c->quantlist[i]*delta+min;
      if(val>max)max=val;
    }

    printf("Minimum scalar value: %f\n",min);
    printf("Maximum scalar value: %f\n",max);

    switch(c->maptype){
    case 1:
      {
        /* lattice codebook.  dump it. */
        int j,k;
        long maxcount=0;
        long **sort=calloc(bins,sizeof(long *));
        long base=c->lengthlist[0];
        countarray=calloc(bins,sizeof(long));

        for(i=0;i<bins;i++)sort[i]=c->quantlist+i;
        qsort(sort,bins,sizeof(long *),ascend);

        for(i=0;i<b->entries;i++)
          if(c->lengthlist[i]>base)base=c->lengthlist[i];

        /* dump a full, correlated count */
        for(j=0;j<b->entries;j++){
          if(c->lengthlist[j]){
            int indexdiv=1;
            printf("%4d: ",j);
            for(k=0;k<b->dim;k++){
              int index= (j/indexdiv)%bins;
              printf("%+3.1f,", c->quantlist[index]*_float32_unpack(c->q_delta)+
                     _float32_unpack(c->q_min));
              indexdiv*=bins;
            }
            printf("\t|");
            for(k=0;k<base-c->lengthlist[j];k++)printf("*");
            printf("\n");
          }
        }

        /* do a rough count */
        for(j=0;j<b->entries;j++){
          int indexdiv=1;
          for(k=0;k<b->dim;k++){
            if(c->lengthlist[j]){
              int index= (j/indexdiv)%bins;
              countarray[index]+=(1<<(base-c->lengthlist[j]));
              indexdiv*=bins;
            }
          }
        }

        /* dump the count */

        {
          long maxcount=0,i,j;
          for(i=0;i<bins;i++)
            if(countarray[i]>maxcount)maxcount=countarray[i];

          for(i=0;i<bins;i++){
            int ptr=sort[i]-c->quantlist;
            int stars=rint(50./maxcount*countarray[ptr]);
            printf("%+08f (%8ld) |",c->quantlist[ptr]*delta+min,countarray[ptr]);
            for(j=0;j<stars;j++)printf("*");
            printf("\n");
          }
        }
      }
      break;
    case 2:
      {
        /* trained, full mapping codebook. */
        printf("Can't do probability dump of a trained [type 2] codebook (yet)\n");
      }
      break;
    }
  }else{
    /* load/count a data file */

    /* do it the simple way; two pass. */
    line=setup_line(in);
    while(line){
      float code;
      char buf[80];
      lines++;

      sprintf(buf,"getting min/max (%.2f::%.2f). lines...",min,max);
      if(!(lines&0xff))spinnit(buf,lines);

      while(!flag && sscanf(line,"%f",&code)==1){
        line=strchr(line,',');
        min=max=code;
        flag=1;
      }

      while(line && sscanf(line,"%f",&code)==1){
        line=strchr(line,',');
        if(line)line++;
        if(code<min)min=code;
        if(code>max)max=code;
      }

      line=setup_line(in);
    }

    if(bins<1){
      if((int)(max-min)==min-max){
        bins=max-min;
      }else{
        bins=25;
      }
    }

    printf("\r                                                     \r");
    printf("Minimum scalar value: %f\n",min);
    printf("Maximum scalar value: %f\n",max);

    if(argv[2]){

      printf("\n counting hits into %ld bins...\n",bins+1);
      countarray=calloc(bins+1,sizeof(long));

      rewind(in);
      line=setup_line(in);
      while(line){
        float code;
        lines--;
        if(!(lines&0xff))spinnit("counting distribution. lines so far...",lines);

        while(line && sscanf(line,"%f",&code)==1){
          line=strchr(line,',');
          if(line)line++;

          code-=min;
          code/=(max-min);
          code*=bins;
          countarray[(int)rint(code)]++;
          total++;
        }

        line=setup_line(in);
      }

      /* make a pretty graph */
      {
        long maxcount=0,i,j;
        for(i=0;i<bins+1;i++)
          if(countarray[i]>maxcount)maxcount=countarray[i];

        printf("\r                                                     \r");
        printf("Total scalars: %ld\n",total);
        for(i=0;i<bins+1;i++){
          int stars=rint(50./maxcount*countarray[i]);
          printf("%08f (%8ld) |",(max-min)/bins*i+min,countarray[i]);
          for(j=0;j<stars;j++)printf("*");
          printf("\n");
        }
      }
    }

    fclose(in);

  }
  printf("\nDone.\n");
  exit(0);
}
int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
  int i,j,tmp;
  memset(s,0,sizeof(*s));

  /* make sure alignment is correct */
  if(oggpack_read1(opb,24)!=0x564342)goto _eofout;
  // if(oggpack_read(opb,24)!=0x564342)goto _eofout;

  /* first the basic parameters */
  s->dim=oggpack_read1(opb,16);
   //s->dim=oggpack_read(opb,16);

  s->entries=oggpack_read1(opb,24);
    //s->entries=oggpack_read(opb,24);

  if(s->entries==-1)goto _eofout;

  /* codeword ordering.... length ordered or unordered? */
  switch((int)oggpack_read1(opb,1)){
    //switch((int)oggpack_read(opb,1)){

  case 0:
    /* unordered */
    s->lengthlist=(int *)malloc(sizeof(*s->lengthlist)*s->entries);

    /* allocated but unused entries? */
    if(oggpack_read1(opb,1)){
    //if(oggpack_read(opb,1)){
      /* yes, unused entries */

      for(i=0;i<s->entries;i++){
	if(oggpack_read1(opb,1)){
   //if(oggpack_read(opb,1)){
	  long num=oggpack_read1(opb,5);
      //long num=oggpack_read(opb,5);
	  if(num==-1)goto _eofout;
	  s->lengthlist[i]=num+1;
	}else
	  s->lengthlist[i]=0;
      }
    }else{
      /* all entries used; no tagging */
      for(i=0;i<s->entries;i++){
	long num=oggpack_read1(opb,5);
   //  long num=oggpack_read(opb,5);
	if(num==-1)goto _eofout;
	s->lengthlist[i]=num+1;
      }
    }
    
    break;
  case 1:
    /* ordered */
    {
      long length=oggpack_read1(opb,5)+1;
       //long length=oggpack_read(opb,5)+1;
      s->lengthlist=(int *)malloc(sizeof(*s->lengthlist)*s->entries);

      for(i=0;i<s->entries;){
	long num=oggpack_read1(opb,vorbisilog(s->entries-i));
     //long num=oggpack_read(opb,vorbisilog(s->entries-i));
	if(num==-1)goto _eofout;
	for(j=0;j<num && i<s->entries;j++,i++)
	  s->lengthlist[i]=length;
	length++;
      }
    }
    break;
  default:
    /* EOF */
    return(-1);
  }
  
  /* Do we have a mapping to unpack? */
  switch((s->maptype=oggpack_read1(opb,4))){
    //switch((s->maptype=oggpack_read(opb,4))){
  case 0:
    /* no mapping */
    break;
  case 1: case 2:
    /* implicitly populated value mapping */
    /* explicitly populated value mapping */

    s->q_min=oggpack_read1(opb,32);
    s->q_delta=oggpack_read1(opb,32);
    tmp = oggpack_read1(opb,5);
    s->q_quant = (tmp & 0xf) + 1;
    s->q_sequencep = ((tmp & 0x10)>>4);
    //s->q_quant=oggpack_read(opb,4)+1;
    //s->q_sequencep=oggpack_read(opb,1);
   
    {
      int quantvals=0;
      switch(s->maptype){
      case 1:
	quantvals=_book_maptype1_quantvals(s);
	break;
      case 2:
	quantvals=s->entries*s->dim;
	break;
      }
      
      /* quantized values */
      s->quantlist=(long *)malloc(sizeof(*s->quantlist)*quantvals);
      for(i=0;i<quantvals;i++)
	s->quantlist[i]=oggpack_read1(opb,s->q_quant);
   //   s->quantlist[i]=oggpack_read(opb,s->q_quant);
      if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
    }
    break;
  default:
    goto _errout;
  }

  /* all set */
  return(0);
  
 _errout:
 _eofout:
  vorbis_staticbook_clear(s);
  return(-1); 
}
Exemple #3
0
int main(int argc,char *argv[]){
  codebook *b;
  static_codebook *c;
  long *lengths;
  long *hits;

  int entries=-1,dim=-1,guard=1;
  FILE *in=NULL;
  char *line,*name;
  long j;

  if(argv[1]==NULL){
    fprintf(stderr,"Need a lattice codebook on the command line.\n");
    exit(1);
  }
  if(argv[2]==NULL){
    fprintf(stderr,"Need a codeword data file on the command line.\n");
    exit(1);
  }
  if(argv[3]!=NULL)guard=0;

  {
    char *ptr;
    char *filename=strdup(argv[1]);

    b=codebook_load(filename);
    c=(static_codebook *)(b->c);
    
    ptr=strrchr(filename,'.');
    if(ptr){
      *ptr='\0';
      name=strdup(filename);
    }else{
      name=strdup(filename);
    }
  }

  if(c->maptype!=1){
    fprintf(stderr,"Provided book is not a latticebook.\n");
    exit(1);
  }

  entries=b->entries;
  dim=b->dim;

  hits=_ogg_malloc(entries*sizeof(long));
  lengths=_ogg_calloc(entries,sizeof(long));
  for(j=0;j<entries;j++)hits[j]=guard;

  in=fopen(argv[2],"r");
  if(!in){
    fprintf(stderr,"Could not open input file %s\n",argv[2]);
    exit(1);
  }

  if(!strrcmp_i(argv[0],"latticetune")){
    long lines=0;
    line=setup_line(in);
    while(line){      
      long code;
      lines++;
      if(!(lines&0xfff))spinnit("codewords so far...",lines);
      
      if(sscanf(line,"%ld",&code)==1)
	hits[code]++;

      line=setup_line(in);
    }
  }

  /* now we simply count already collated by-entry data */
  if(!strrcmp_i(argv[0],"res0tune") || !strrcmp_i(argv[0],"res1tune")){

    line=setup_line(in);
    while(line){

      /* code:hits\n */
      /* likely to have multiple listing for each code entry; must
         accumulate */

      char *pos=strchr(line,':');
      if(pos){
	long code=atol(line);
	long val=atol(pos+1); 
	hits[code]+=val;
      }

      line=setup_line(in);
    }
  }

  fclose(in);

  /* build the codeword lengths */
  build_tree_from_lengths0(entries,hits,lengths);

  c->lengthlist=lengths;
  write_codebook(stdout,name,c); 

  {
    long bins=_book_maptype1_quantvals(c);
    long i,k,base=c->lengthlist[0];
    for(i=0;i<entries;i++)
      if(c->lengthlist[i]>base)base=c->lengthlist[i];
    
    for(j=0;j<entries;j++){
      if(c->lengthlist[j]){
	int indexdiv=1;
	fprintf(stderr,"%4ld: ",j);
	for(k=0;k<c->dim;k++){      
	  int index= (j/indexdiv)%bins;
	  fprintf(stderr,"%+3.1f,", c->quantlist[index]*_float32_unpack(c->q_delta)+
		 _float32_unpack(c->q_min));
	  indexdiv*=bins;
	}
	fprintf(stderr,"\t|");
	for(k=0;k<base-c->lengthlist[j];k++)fprintf(stderr,"*");
	fprintf(stderr,"\n");
      }
    }
  }
  
  fprintf(stderr,"\r                                                     "
	  "\nDone.\n");
  exit(0);
}
Exemple #4
0
int main(int argc,char *argv[]) {
    codebook *b;
    static_codebook *c;
    int entries=-1,dim=-1;
    float min,del;
    char *name;
    long i,j;
    float *suggestions;
    int suggcount=0;

    if(argv[1]==NULL) {
        fprintf(stderr,"Need a lattice book on the command line.\n");
        exit(1);
    }

    {
        char *ptr;
        char *filename=strdup(argv[1]);

        b=codebook_load(filename);
        c=(static_codebook *)(b->c);

        ptr=strrchr(filename,'.');
        if(ptr) {
            *ptr='\0';
            name=strdup(filename);
        } else {
            name=strdup(filename);
        }
    }

    if(c->maptype!=1) {
        fprintf(stderr,"Provided book is not a latticebook.\n");
        exit(1);
    }

    entries=b->entries;
    dim=b->dim;
    min=_float32_unpack(c->q_min);
    del=_float32_unpack(c->q_delta);

    /* Do we want to gen a threshold hint? */
    if(c->q_sequencep==0) {
        /* yes. Discard any preexisting threshhold hint */
        long quantvals=_book_maptype1_quantvals(c);
        long **quantsort=alloca(quantvals*sizeof(long *));
        encode_aux_threshmatch *t=_ogg_calloc(1,sizeof(encode_aux_threshmatch));
        c->thresh_tree=t;

        fprintf(stderr,"Adding threshold hint to %s...\n",name);

        /* partial/complete suggestions */
        if(argv[2]) {
            char *ptr=strdup(argv[2]);
            suggestions=alloca(sizeof(float)*quantvals);

            for(suggcount=0; ptr && suggcount<quantvals; suggcount++) {
                char *ptr2=strchr(ptr,',');
                if(ptr2)*ptr2++='\0';
                suggestions[suggcount]=atof(ptr);
                ptr=ptr2;
            }
        }

        /* simplest possible threshold hint only */
        t->quantthresh=_ogg_calloc(quantvals-1,sizeof(float));
        t->quantmap=_ogg_calloc(quantvals,sizeof(int));
        t->threshvals=quantvals;
        t->quantvals=quantvals;

        /* the quantvals may not be in order; sort em first */
        for(i=0; i<quantvals; i++)quantsort[i]=c->quantlist+i;
        qsort(quantsort,quantvals,sizeof(long *),longsort);

        /* ok, gen the map and thresholds */
        for(i=0; i<quantvals; i++)t->quantmap[i]=quantsort[i]-c->quantlist;
        for(i=0; i<quantvals-1; i++) {
            float v1=*(quantsort[i])*del+min;
            float v2=*(quantsort[i+1])*del+min;

            for(j=0; j<suggcount; j++)
                if(v1<suggestions[j] && suggestions[j]<v2) {
                    t->quantthresh[i]=suggestions[j];
                    break;
                }

            if(j==suggcount) {
                t->quantthresh[i]=(v1+v2)*.5;
            }
        }
    }

    /* Do we want to gen a pigeonhole hint? */
#if 0
    for(i=0; i<entries; i++)if(c->lengthlist[i]==0)break;
    if(c->q_sequencep || i<entries) {
        long **tempstack;
        long *tempcount;
        long *temptrack;
        float *tempmin;
        float *tempmax;
        long totalstack=0;
        long pigeons;
        long subpigeons;
        long quantvals=_book_maptype1_quantvals(c);
        int changep=1,factor;

        encode_aux_pigeonhole *p=_ogg_calloc(1,sizeof(encode_aux_pigeonhole));
        c->pigeon_tree=p;

        fprintf(stderr,"Adding pigeonhole hint to %s...\n",name);

        /* the idea is that we quantize uniformly, even in a nonuniform
           lattice, so that quantization of one scalar has a predictable
           result on the next sequential scalar in a greedy matching
           algorithm.  We generate a lookup based on the quantization of
           the vector (pigeonmap groups quantized entries together) and
           list the entries that could possible be the best fit for any
           given member of that pigeonhole.  The encode process then has a
           much smaller list to brute force */

        /* find our pigeonhole-specific quantization values, fill in the
           quant value->pigeonhole map */
        factor=3;
        p->del=del;
        p->min=min;
        p->quantvals=quantvals;
        {
            int max=0;
            for(i=0; i<quantvals; i++)if(max<c->quantlist[i])max=c->quantlist[i];
            p->mapentries=max;
        }
        p->pigeonmap=_ogg_malloc(p->mapentries*sizeof(long));
        p->quantvals=(quantvals+factor-1)/factor;

        /* pigeonhole roughly on the boundaries of the quantvals; the
           exact pigeonhole grouping is an optimization issue, not a
           correctness issue */
        for(i=0; i<p->mapentries; i++) {
            float thisval=del*i+min; /* middle of the quant zone */
            int quant=0;
            float err=fabs(c->quantlist[0]*del+min-thisval);
            for(j=1; j<quantvals; j++) {
                float thiserr=fabs(c->quantlist[j]*del+min-thisval);
                if(thiserr<err) {
                    quant=j/factor;
                    err=thiserr;
                }
            }
            p->pigeonmap[i]=quant;
        }

        /* pigeonmap complete.  Now do the grungy business of finding the
        entries that could possibly be the best fit for a value appearing
        in the pigeonhole. The trick that allows the below to work is the
        uniform quantization; even though the scalars may be 'sequential'
        (each a delta from the last), the uniform quantization means that
        the error variance is *not* dependant.  Given a pigeonhole and an
        entry, we can find the minimum and maximum possible errors
        (relative to the entry) for any point that could appear in the
        pigeonhole */

        /* must iterate over both pigeonholes and entries */
        /* temporarily (in order to avoid thinking hard), we grow each
           pigeonhole separately, the build a stack of 'em later */
        pigeons=1;
        subpigeons=1;
        for(i=0; i<dim; i++)subpigeons*=p->mapentries;
        for(i=0; i<dim; i++)pigeons*=p->quantvals;
        temptrack=_ogg_calloc(dim,sizeof(long));
        tempmin=_ogg_calloc(dim,sizeof(float));
        tempmax=_ogg_calloc(dim,sizeof(float));
        tempstack=_ogg_calloc(pigeons,sizeof(long *));
        tempcount=_ogg_calloc(pigeons,sizeof(long));

        while(1) {
            float errorpost=-1;
            char buffer[80];

            /* map our current pigeonhole to a 'big pigeonhole' so we know
               what list we're after */
            int entry=0;
            for(i=dim-1; i>=0; i--)entry=entry*p->quantvals+p->pigeonmap[temptrack[i]];
            setvals(dim,p,temptrack,tempmin,tempmax,c->q_sequencep);
            sprintf(buffer,"Building pigeonhole search list [%ld]...",totalstack);


            /* Search all entries to find the one with the minimum possible
               maximum error.  Record that error */
            for(i=0; i<entries; i++) {
                if(c->lengthlist[i]>0) {
                    float this=maxerror(dim,b->valuelist+i*dim,p,
                                        temptrack,tempmin,tempmax);
                    if(errorpost==-1 || this<errorpost)errorpost=this;
                    spinnit(buffer,subpigeons);
                }
            }

            /* Our search list will contain all entries with a minimum
               possible error <= our errorpost */
            for(i=0; i<entries; i++)
                if(c->lengthlist[i]>0) {
                    spinnit(buffer,subpigeons);
                    if(minerror(dim,b->valuelist+i*dim,p,
                                temptrack,tempmin,tempmax)<errorpost)
                        totalstack+=addtosearch(entry,tempstack,tempcount,i);
                }

            for(i=0; i<dim; i++) {
                temptrack[i]++;
                if(temptrack[i]<p->mapentries)break;
                temptrack[i]=0;
            }
            if(i==dim)break;
            subpigeons--;
        }
Exemple #5
0
void write_codebook(FILE *out,char *name,const static_codebook *c){
  encode_aux_pigeonhole *p=c->pigeon_tree;
  encode_aux_threshmatch *t=c->thresh_tree;
  encode_aux_nearestmatch *n=c->nearest_tree;
  int i,j,k;

  /* save the book in C header form */

  /* first, the static vectors, then the book structure to tie it together. */
  /* quantlist */
  if(c->quantlist){
    long vals=(c->maptype==1?_book_maptype1_quantvals(c):c->entries*c->dim);
    fprintf(out,"static long _vq_quantlist_%s[] = {\n",name);
    for(j=0;j<vals;j++){
      fprintf(out,"\t%ld,\n",c->quantlist[j]);
    }
    fprintf(out,"};\n\n");
  }

  /* lengthlist */
  fprintf(out,"static long _vq_lengthlist_%s[] = {\n",name);
  for(j=0;j<c->entries;){
    fprintf(out,"\t");
    for(k=0;k<16 && j<c->entries;k++,j++)
      fprintf(out,"%2ld,",c->lengthlist[j]);
    fprintf(out,"\n");
  }
  fprintf(out,"};\n\n");

  if(t){
    /* quantthresh */
    fprintf(out,"static float _vq_quantthresh_%s[] = {\n",name);
    for(j=0;j<t->threshvals-1;){
      fprintf(out,"\t");
      for(k=0;k<8 && j<t->threshvals-1;k++,j++)
	fprintf(out,"%.5g, ",t->quantthresh[j]);
      fprintf(out,"\n");
    }
    fprintf(out,"};\n\n");

    /* quantmap */
    fprintf(out,"static long _vq_quantmap_%s[] = {\n",name);
    for(j=0;j<t->threshvals;){
      fprintf(out,"\t");
      for(k=0;k<8 && j<t->threshvals;k++,j++)
	fprintf(out,"%5ld,",t->quantmap[j]);
      fprintf(out,"\n");
    }
    fprintf(out,"};\n\n");  

    fprintf(out,"static encode_aux_threshmatch _vq_auxt_%s = {\n",name);
    fprintf(out,"\t_vq_quantthresh_%s,\n",name);
    fprintf(out,"\t_vq_quantmap_%s,\n",name);
    fprintf(out,"\t%d,\n",t->quantvals);
    fprintf(out,"\t%d\n};\n\n",t->threshvals);
  }

  if(p){
    int pigeons=1;
    for(i=0;i<c->dim;i++)pigeons*=p->quantvals;

    /* pigeonmap */
    fprintf(out,"static long _vq_pigeonmap_%s[] = {\n",name);
    for(j=0;j<p->mapentries;){
      fprintf(out,"\t");
      for(k=0;k<8 && j<p->mapentries;k++,j++)
	fprintf(out,"%5ld, ",p->pigeonmap[j]);
      fprintf(out,"\n");
    }
    fprintf(out,"};\n\n");
    /* fitlist */
    fprintf(out,"static long _vq_fitlist_%s[] = {\n",name);
    for(j=0;j<p->fittotal;){
      fprintf(out,"\t");
      for(k=0;k<8 && j<p->fittotal;k++,j++)
	fprintf(out,"%5ld, ",p->fitlist[j]);
      fprintf(out,"\n");
    }
    fprintf(out,"};\n\n");
    /* fitmap */
    fprintf(out,"static long _vq_fitmap_%s[] = {\n",name);
    for(j=0;j<pigeons;){
      fprintf(out,"\t");
      for(k=0;k<8 && j<pigeons;k++,j++)
	fprintf(out,"%5ld, ",p->fitmap[j]);
      fprintf(out,"\n");
    }
    fprintf(out,"};\n\n");
    /* fitlength */
    fprintf(out,"static long _vq_fitlength_%s[] = {\n",name);
    for(j=0;j<pigeons;){
      fprintf(out,"\t");
      for(k=0;k<8 && j<pigeons;k++,j++)
	fprintf(out,"%5ld, ",p->fitlength[j]);
      fprintf(out,"\n");
    }
    fprintf(out,"};\n\n");

    fprintf(out,"static encode_aux_pigeonhole _vq_auxp_%s = {\n",name);
    fprintf(out,"\t%g, %g, %d, %d,\n",
	    p->min,p->del,p->mapentries,p->quantvals);

    fprintf(out,"\t_vq_pigeonmap_%s,\n",name);

    fprintf(out,"\t%ld,\n",p->fittotal);
    fprintf(out,"\t_vq_fitlist_%s,\n",name);
    fprintf(out,"\t_vq_fitmap_%s,\n",name);
    fprintf(out,"\t_vq_fitlength_%s\n};\n\n",name);
  }

  if(n){
    
    /* ptr0 */
    fprintf(out,"static long _vq_ptr0_%s[] = {\n",name);
    for(j=0;j<n->aux;){
      fprintf(out,"\t");
      for(k=0;k<8 && j<n->aux;k++,j++)
	fprintf(out,"%6ld,",n->ptr0[j]);
      fprintf(out,"\n");
    }
    fprintf(out,"};\n\n");
    
    /* ptr1 */
    fprintf(out,"static long _vq_ptr1_%s[] = {\n",name);
    for(j=0;j<n->aux;){
      fprintf(out,"\t");
      for(k=0;k<8 && j<n->aux;k++,j++)
	fprintf(out,"%6ld,",n->ptr1[j]);
      fprintf(out,"\n");
    }
    fprintf(out,"};\n\n");
    
    /* p */
    fprintf(out,"static long _vq_p_%s[] = {\n",name);
    for(j=0;j<n->aux;){
      fprintf(out,"\t");
      for(k=0;k<8 && j<n->aux;k++,j++)
	fprintf(out,"%6ld,",n->p[j]*c->dim);
      fprintf(out,"\n");
    }
    fprintf(out,"};\n\n");
    
    /* q */
    fprintf(out,"static long _vq_q_%s[] = {\n",name);
    for(j=0;j<n->aux;){
      fprintf(out,"\t");
      for(k=0;k<8 && j<n->aux;k++,j++)
	fprintf(out,"%6ld,",n->q[j]*c->dim);
      fprintf(out,"\n");
    }
    fprintf(out,"};\n\n");
  
    fprintf(out,"static encode_aux_nearestmatch _vq_auxn_%s = {\n",name);
    fprintf(out,"\t_vq_ptr0_%s,\n",name);
    fprintf(out,"\t_vq_ptr1_%s,\n",name);
    fprintf(out,"\t_vq_p_%s,\n",name);
    fprintf(out,"\t_vq_q_%s,\n",name);
    fprintf(out,"\t%ld, %ld\n};\n\n",n->aux,n->aux);
  }

  /* tie it all together */
  
  fprintf(out,"static static_codebook %s = {\n",name);
  
  fprintf(out,"\t%ld, %ld,\n",c->dim,c->entries);
  fprintf(out,"\t_vq_lengthlist_%s,\n",name);
  fprintf(out,"\t%d, %ld, %ld, %d, %d,\n",
          c->maptype,c->q_min,c->q_delta,c->q_quant,c->q_sequencep);
  if(c->quantlist)
    fprintf(out,"\t_vq_quantlist_%s,\n",name);
  else
    fprintf(out,"\tNULL,\n");

  if(n)
    fprintf(out,"\t&_vq_auxn_%s,\n",name);
  else
    fprintf(out,"\tNULL,\n");
  if(t)
    fprintf(out,"\t&_vq_auxt_%s,\n",name);
  else
    fprintf(out,"\tNULL,\n");
  if(p)
    fprintf(out,"\t&_vq_auxp_%s,\n",name);
  else
    fprintf(out,"\tNULL,\n");

  fprintf(out,"\t0\n};\n\n");
}
Exemple #6
0
codebook *codebook_load(char *filename){
  codebook *b=_ogg_calloc(1,sizeof(codebook));
  static_codebook *c=(static_codebook *)(b->c=_ogg_calloc(1,sizeof(static_codebook)));
  encode_aux_nearestmatch *a=NULL;
  encode_aux_threshmatch *t=NULL;
  encode_aux_pigeonhole *p=NULL;
  int quant_to_read=0;
  FILE *in=fopen(filename,"r");
  char *line;
  long i;

  if(in==NULL){
    fprintf(stderr,"Couldn't open codebook %s\n",filename);
    exit(1);
  }

  /* find the codebook struct */
  find_seek_to(in,"static static_codebook ");

  /* get the major important values */
  line=get_line(in);
  if(sscanf(line,"%ld, %ld,",
	    &(c->dim),&(c->entries))!=2){
    fprintf(stderr,"1: syntax in %s in line:\t %s",filename,line);
    exit(1);
  }
  line=get_line(in);
  line=get_line(in);
  if(sscanf(line,"%d, %ld, %ld, %d, %d,",
	    &(c->maptype),&(c->q_min),&(c->q_delta),&(c->q_quant),
	    &(c->q_sequencep))!=5){
    fprintf(stderr,"1: syntax in %s in line:\t %s",filename,line);
    exit(1);
  }
  
  /* find the auxiliary encode struct[s] (if any) */
  if(find_seek_to(in,"static encode_aux_nearestmatch _vq_aux")){
    /* how big? */
    c->nearest_tree=a=_ogg_calloc(1,sizeof(encode_aux_nearestmatch));
    line=get_line(in);
    line=get_line(in);
    line=get_line(in);
    line=get_line(in);
    line=get_line(in);
    if(sscanf(line,"%ld, %ld",&(a->aux),&(a->alloc))!=2){
      fprintf(stderr,"2: syntax in %s in line:\t %s",filename,line);
      exit(1);
    }

    /* load ptr0 */
    find_seek_to(in,"static long _vq_ptr0");
    reset_next_value();
    a->ptr0=_ogg_malloc(sizeof(long)*a->aux);
    for(i=0;i<a->aux;i++)
      if(get_next_ivalue(in,a->ptr0+i)){
	fprintf(stderr,"out of data while reading codebook %s\n",filename);
	exit(1);
      }
    
    /* load ptr1 */
    find_seek_to(in,"static long _vq_ptr1");
    reset_next_value();
    a->ptr1=_ogg_malloc(sizeof(long)*a->aux);
    for(i=0;i<a->aux;i++)
      if(get_next_ivalue(in,a->ptr1+i)){
	fprintf(stderr,"out of data while reading codebook %s\n",filename);
	exit(1);
    }
    
    
    /* load p */
    find_seek_to(in,"static long _vq_p_");
    reset_next_value();
    a->p=_ogg_malloc(sizeof(long)*a->aux);
    for(i=0;i<a->aux;i++)
      if(get_next_ivalue(in,a->p+i)){
	fprintf(stderr,"out of data while reading codebook %s\n",filename);
	exit(1);
      }
    
    /* load q */
    find_seek_to(in,"static long _vq_q_");
    reset_next_value();
    a->q=_ogg_malloc(sizeof(long)*a->aux);
    for(i=0;i<a->aux;i++)
      if(get_next_ivalue(in,a->q+i)){
	fprintf(stderr,"out of data while reading codebook %s\n",filename);
	exit(1);
      }    
  }
  
  if(find_seek_to(in,"static encode_aux_threshmatch _vq_aux")){
    /* how big? */
    c->thresh_tree=t=_ogg_calloc(1,sizeof(encode_aux_threshmatch));
    line=get_line(in);
    line=get_line(in);
    line=get_line(in);
    if(sscanf(line,"%d",&(t->quantvals))!=1){
      fprintf(stderr,"3: syntax in %s in line:\t %s",filename,line);
      exit(1);
    }
    line=get_line(in);
    if(sscanf(line,"%d",&(t->threshvals))!=1){
      fprintf(stderr,"4: syntax in %s in line:\t %s",filename,line);
      exit(1);
    }
    /* load quantthresh */
    find_seek_to(in,"static float _vq_quantthresh_");
    reset_next_value();
    t->quantthresh=_ogg_malloc(sizeof(float)*t->threshvals);
    for(i=0;i<t->threshvals-1;i++)
      if(get_next_value(in,t->quantthresh+i)){
	fprintf(stderr,"out of data 1 while reading codebook %s\n",filename);
	exit(1);
      }    
    /* load quantmap */
    find_seek_to(in,"static long _vq_quantmap_");
    reset_next_value();
    t->quantmap=_ogg_malloc(sizeof(long)*t->threshvals);
    for(i=0;i<t->threshvals;i++)
      if(get_next_ivalue(in,t->quantmap+i)){
	fprintf(stderr,"out of data 2 while reading codebook %s\n",filename);
	exit(1);
      }    
  }
    
  if(find_seek_to(in,"static encode_aux_pigeonhole _vq_aux")){
    int pigeons=1,i;
    /* how big? */
    c->pigeon_tree=p=_ogg_calloc(1,sizeof(encode_aux_pigeonhole));
    line=get_line(in);
    if(sscanf(line,"%f, %f, %d, %d",&(p->min),&(p->del),
	      &(p->mapentries),&(p->quantvals))!=4){
      fprintf(stderr,"5: syntax in %s in line:\t %s",filename,line);
      exit(1);
    }
    line=get_line(in);
    line=get_line(in);
    if(sscanf(line,"%ld",&(p->fittotal))!=1){
      fprintf(stderr,"6: syntax in %s in line:\t %s",filename,line);
      exit(1);
    }
    /* load pigeonmap */
    find_seek_to(in,"static long _vq_pigeonmap_");
    reset_next_value();
    p->pigeonmap=_ogg_malloc(sizeof(long)*p->mapentries);
    for(i=0;i<p->mapentries;i++)
      if(get_next_ivalue(in,p->pigeonmap+i)){
	fprintf(stderr,"out of data (pigeonmap) while reading codebook %s\n",filename);
	exit(1);
      }    
    /* load fitlist */
    find_seek_to(in,"static long _vq_fitlist_");
    reset_next_value();
    p->fitlist=_ogg_malloc(sizeof(long)*p->fittotal);
    for(i=0;i<p->fittotal;i++)
      if(get_next_ivalue(in,p->fitlist+i)){
	fprintf(stderr,"out of data (fitlist) while reading codebook %s\n",filename);
	exit(1);
      }    
    /* load fitmap */
    find_seek_to(in,"static long _vq_fitmap_");
    reset_next_value();
    for(i=0;i<c->dim;i++)pigeons*=p->quantvals;
    p->fitmap=_ogg_malloc(sizeof(long)*pigeons);
    for(i=0;i<pigeons;i++)
      if(get_next_ivalue(in,p->fitmap+i)){
	fprintf(stderr,"out of data (fitmap) while reading codebook %s\n",filename);
	exit(1);
      }    
 
    /* load fitlength */
    find_seek_to(in,"static long _vq_fitlength_");
    reset_next_value();
    p->fitlength=_ogg_malloc(sizeof(long)*pigeons);
    for(i=0;i<pigeons;i++)
      if(get_next_ivalue(in,p->fitlength+i)){
	fprintf(stderr,"out of data (fitlength) while reading codebook %s\n",filename);
	exit(1);
      }    
  }

  switch(c->maptype){
  case 0:
    quant_to_read=0;
    break;
  case 1:
    quant_to_read=_book_maptype1_quantvals(c);
    break;
  case 2:
    quant_to_read=c->entries*c->dim;
    break;
  }
    
  /* load the quantized entries */
  find_seek_to(in,"static long _vq_quantlist_");
  reset_next_value();
  c->quantlist=_ogg_malloc(sizeof(long)*quant_to_read);
  for(i=0;i<quant_to_read;i++)
    if(get_next_ivalue(in,c->quantlist+i)){
      fprintf(stderr,"out of data while reading codebook %s\n",filename);
      exit(1);
    }
  
  /* load the lengthlist */
  find_seek_to(in,"_lengthlist");
  reset_next_value();
  c->lengthlist=_ogg_malloc(sizeof(long)*c->entries);
  for(i=0;i<c->entries;i++)
    if(get_next_ivalue(in,c->lengthlist+i)){
      fprintf(stderr,"out of data while reading codebook %s\n",filename);
      exit(1);
    }

  /* got it all */
  fclose(in);
  
  vorbis_book_init_encode(b,c);

  return(b);
}
Exemple #7
0
int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
  long i,j;
  int ordered=0;

  /* first the basic parameters */
  oggpack_write(opb,0x564342,24);
  oggpack_write(opb,c->dim,16);
  oggpack_write(opb,c->entries,24);

  /* pack the codewords.  There are two packings; length ordered and
     length random.  Decide between the two now. */

  for(i=1;i<c->entries;i++)
    if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break;
  if(i==c->entries)ordered=1;

  if(ordered){
    /* length ordered.  We only need to say how many codewords of
       each length.  The actual codewords are generated
       deterministically */

    long count=0;
    oggpack_write(opb,1,1);  /* ordered */
    oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */

    for(i=1;i<c->entries;i++){
      long thisx=c->lengthlist[i];
      long last=c->lengthlist[i-1];
      if(thisx>last){
	for(j=last;j<thisx;j++){
	  oggpack_write(opb,i-count,_ilog(c->entries-count));
	  count=i;
	}
      }
    }
    oggpack_write(opb,i-count,_ilog(c->entries-count));

  }else{
    /* length random.  Again, we don't code the codeword itself, just
       the length.  This time, though, we have to encode each length */
    oggpack_write(opb,0,1);   /* unordered */

    /* algortihmic mapping has use for 'unused entries', which we tag
       here.  The algorithmic mapping happens as usual, but the unused
       entry has no codeword. */
    for(i=0;i<c->entries;i++)
      if(c->lengthlist[i]==0)break;

    if(i==c->entries){
      oggpack_write(opb,0,1); /* no unused entries */
      for(i=0;i<c->entries;i++)
	oggpack_write(opb,c->lengthlist[i]-1,5);
    }else{
      oggpack_write(opb,1,1); /* we have unused entries; thus we tag */
      for(i=0;i<c->entries;i++){
	if(c->lengthlist[i]==0){
	  oggpack_write(opb,0,1);
	}else{
	  oggpack_write(opb,1,1);
	  oggpack_write(opb,c->lengthlist[i]-1,5);
	}
      }
    }
  }

  /* is the entry number the desired return value, or do we have a
     mapping? If we have a mapping, what type? */
  oggpack_write(opb,c->maptype,4);
  switch(c->maptype){
  case 0:
    /* no mapping */
    break;
  case 1:case 2:
    /* implicitly populated value mapping */
    /* explicitly populated value mapping */

    if(!c->quantlist){
      /* no quantlist?  error */
      return(-1);
    }

    /* values that define the dequantization */
    oggpack_write(opb,c->q_min,32);
    oggpack_write(opb,c->q_delta,32);
    oggpack_write(opb,c->q_quant-1,4);
    oggpack_write(opb,c->q_sequencep,1);

    {
      int quantvals;
      switch(c->maptype){
      case 1:
	/* a single column of (c->entries/c->dim) quantized values for
	   building a full value list algorithmically (square lattice) */
	quantvals=_book_maptype1_quantvals(c);
	break;
      case 2:
	/* every value (c->entries*c->dim total) specified explicitly */
	quantvals=c->entries*c->dim;
	break;
      default: /* NOT_REACHABLE */
	quantvals=-1;
      }

      /* quantized values */
      for(i=0;i<quantvals;i++)
	oggpack_write(opb,labs(c->quantlist[i]),c->q_quant);

    }
    break;
  default:
    /* error case; we don't have any other map types now */
    return(-1);
  }

  return(0);
}