examples/SFExamples/oggvorbiscodec94/src/libvorbis/lib/codebook.c

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
00004  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00005  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00006  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00007  *                                                                  *
00008  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
00009  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
00010  *                                                                  *
00011  ********************************************************************
00012 
00013  function: basic codebook pack/unpack/code/decode operations
00014  last mod: $Id: codebook.c 7187 2004-07-20 07:24:27Z xiphmont $
00015 
00016  ********************************************************************/
00017 
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <math.h>
00021 #include "ogg/ogg.h"
00022 #include "vorbis/codec.h"
00023 #include "codebook.h"
00024 #include "scales.h"
00025 #include "misc.h"
00026 #include "os.h"
00027 
00028 /* packs the given codebook into the bitstream **************************/
00029 
00030 int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
00031   long i,j;
00032   int ordered=0;
00033 
00034   /* first the basic parameters */
00035   oggpack_write(opb,0x564342,24);
00036   oggpack_write(opb,c->dim,16);
00037   oggpack_write(opb,c->entries,24);
00038 
00039   /* pack the codewords.  There are two packings; length ordered and
00040      length random.  Decide between the two now. */
00041   
00042   for(i=1;i<c->entries;i++)
00043     if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break;
00044   if(i==c->entries)ordered=1;
00045   
00046   if(ordered){
00047     /* length ordered.  We only need to say how many codewords of
00048        each length.  The actual codewords are generated
00049        deterministically */
00050 
00051     long count=0;
00052     oggpack_write(opb,1,1);  /* ordered */
00053     oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */
00054 
00055     for(i=1;i<c->entries;i++){
00056       long temp=c->lengthlist[i];
00057       long last=c->lengthlist[i-1];
00058       if(temp>last){
00059         for(j=last;j<temp;j++){
00060           oggpack_write(opb,i-count,_ilog(c->entries-count));
00061           count=i;
00062         }
00063       }
00064     }
00065     oggpack_write(opb,i-count,_ilog(c->entries-count));
00066     
00067   }else{
00068     /* length random.  Again, we don't code the codeword itself, just
00069        the length.  This time, though, we have to encode each length */
00070     oggpack_write(opb,0,1);   /* unordered */
00071     
00072     /* algortihmic mapping has use for 'unused entries', which we tag
00073        here.  The algorithmic mapping happens as usual, but the unused
00074        entry has no codeword. */
00075     for(i=0;i<c->entries;i++)
00076       if(c->lengthlist[i]==0)break;
00077 
00078     if(i==c->entries){
00079       oggpack_write(opb,0,1); /* no unused entries */
00080       for(i=0;i<c->entries;i++)
00081         oggpack_write(opb,c->lengthlist[i]-1,5);
00082     }else{
00083       oggpack_write(opb,1,1); /* we have unused entries; thus we tag */
00084       for(i=0;i<c->entries;i++){
00085         if(c->lengthlist[i]==0){
00086           oggpack_write(opb,0,1);
00087         }else{
00088           oggpack_write(opb,1,1);
00089           oggpack_write(opb,c->lengthlist[i]-1,5);
00090         }
00091       }
00092     }
00093   }
00094 
00095   /* is the entry number the desired return value, or do we have a
00096      mapping? If we have a mapping, what type? */
00097   oggpack_write(opb,c->maptype,4);
00098   switch(c->maptype){
00099   case 0:
00100     /* no mapping */
00101     break;
00102   case 1:case 2:
00103     /* implicitly populated value mapping */
00104     /* explicitly populated value mapping */
00105     
00106     if(!c->quantlist){
00107       /* no quantlist?  error */
00108       return(-1);
00109     }
00110     
00111     /* values that define the dequantization */
00112     oggpack_write(opb,c->q_min,32);
00113     oggpack_write(opb,c->q_delta,32);
00114     oggpack_write(opb,c->q_quant-1,4);
00115     oggpack_write(opb,c->q_sequencep,1);
00116     
00117     {
00118       int quantvals;
00119       switch(c->maptype){
00120       case 1:
00121         /* a single column of (c->entries/c->dim) quantized values for
00122            building a full value list algorithmically (square lattice) */
00123         quantvals=_book_maptype1_quantvals(c);
00124         break;
00125       case 2:
00126         /* every value (c->entries*c->dim total) specified explicitly */
00127         quantvals=c->entries*c->dim;
00128         break;
00129       default: /* NOT_REACHABLE */
00130         quantvals=-1;
00131       }
00132 
00133       /* quantized values */
00134       for(i=0;i<quantvals;i++)
00135         oggpack_write(opb,labs(c->quantlist[i]),c->q_quant);
00136 
00137     }
00138     break;
00139   default:
00140     /* error case; we don't have any other map types now */
00141     return(-1);
00142   }
00143 
00144   return(0);
00145 }
00146 
00147 /* unpacks a codebook from the packet buffer into the codebook struct,
00148    readies the codebook auxiliary structures for decode *************/
00149 int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
00150   long i,j;
00151   memset(s,0,sizeof(*s));
00152   s->allocedp=1;
00153 
00154   /* make sure alignment is correct */
00155   if(oggpack_read(opb,24)!=0x564342)goto _eofout;
00156 
00157   /* first the basic parameters */
00158   s->dim=oggpack_read(opb,16);
00159   s->entries=oggpack_read(opb,24);
00160   if(s->entries==-1)goto _eofout;
00161 
00162   /* codeword ordering.... length ordered or unordered? */
00163   switch((int)oggpack_read(opb,1)){
00164   case 0:
00165     /* unordered */
00166     s->lengthlist=(long int*)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
00167 
00168     /* allocated but unused entries? */
00169     if(oggpack_read(opb,1)){
00170       /* yes, unused entries */
00171 
00172       for(i=0;i<s->entries;i++){
00173         if(oggpack_read(opb,1)){
00174           long num=oggpack_read(opb,5);
00175           if(num==-1)goto _eofout;
00176           s->lengthlist[i]=num+1;
00177         }else
00178           s->lengthlist[i]=0;
00179       }
00180     }else{
00181       /* all entries used; no tagging */
00182       for(i=0;i<s->entries;i++){
00183         long num=oggpack_read(opb,5);
00184         if(num==-1)goto _eofout;
00185         s->lengthlist[i]=num+1;
00186       }
00187     }
00188     
00189     break;
00190   case 1:
00191     /* ordered */
00192     {
00193       long length=oggpack_read(opb,5)+1;
00194       s->lengthlist=(long int*)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
00195 
00196       for(i=0;i<s->entries;){
00197         long num=oggpack_read(opb,_ilog(s->entries-i));
00198         if(num==-1)goto _eofout;
00199         for(j=0;j<num && i<s->entries;j++,i++)
00200           s->lengthlist[i]=length;
00201         length++;
00202       }
00203     }
00204     break;
00205   default:
00206     /* EOF */
00207     return(-1);
00208   }
00209   
00210   /* Do we have a mapping to unpack? */
00211   switch((s->maptype=oggpack_read(opb,4))){
00212   case 0:
00213     /* no mapping */
00214     break;
00215   case 1: case 2:
00216     /* implicitly populated value mapping */
00217     /* explicitly populated value mapping */
00218 
00219     s->q_min=oggpack_read(opb,32);
00220     s->q_delta=oggpack_read(opb,32);
00221     s->q_quant=oggpack_read(opb,4)+1;
00222     s->q_sequencep=oggpack_read(opb,1);
00223 
00224     {
00225       int quantvals=0;
00226       switch(s->maptype){
00227       case 1:
00228         quantvals=_book_maptype1_quantvals(s);
00229         break;
00230       case 2:
00231         quantvals=s->entries*s->dim;
00232         break;
00233       }
00234       
00235       /* quantized values */
00236       s->quantlist=(long int*)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
00237       for(i=0;i<quantvals;i++)
00238         s->quantlist[i]=oggpack_read(opb,s->q_quant);
00239       
00240       if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
00241     }
00242     break;
00243   default:
00244     goto _errout;
00245   }
00246 
00247   /* all set */
00248   return(0);
00249   
00250  _errout:
00251  _eofout:
00252   vorbis_staticbook_clear(s);
00253   return(-1); 
00254 }
00255 
00256 /* returns the number of bits ************************************************/
00257 int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){
00258   oggpack_write(b,book->codelist[a],book->c->lengthlist[a]);
00259   return(book->c->lengthlist[a]);
00260 }
00261 
00262 /* One the encode side, our vector writers are each designed for a
00263 specific purpose, and the encoder is not flexible without modification:
00264 
00265 The LSP vector coder uses a single stage nearest-match with no
00266 interleave, so no step and no error return.  This is specced by floor0
00267 and doesn't change.
00268 
00269 Residue0 encoding interleaves, uses multiple stages, and each stage
00270 peels of a specific amount of resolution from a lattice (thus we want
00271 to match by threshold, not nearest match).  Residue doesn't *have* to
00272 be encoded that way, but to change it, one will need to add more
00273 infrastructure on the encode side (decode side is specced and simpler) */
00274 
00275 /* floor0 LSP (single stage, non interleaved, nearest match) */
00276 /* returns entry number and *modifies a* to the quantization value *****/
00277 int vorbis_book_errorv(codebook *book,float *a){
00278   int dim=book->dim,k;
00279   int best=_best(book,a,1);
00280   for(k=0;k<dim;k++)
00281     a[k]=(book->valuelist+best*dim)[k];
00282   return(best);
00283 }
00284 
00285 /* returns the number of bits and *modifies a* to the quantization value *****/
00286 int vorbis_book_encodev(codebook *book,int best,float *a,oggpack_buffer *b){
00287   int k,dim=book->dim;
00288   for(k=0;k<dim;k++)
00289     a[k]=(book->valuelist+best*dim)[k];
00290   return(vorbis_book_encode(book,best,b));
00291 }
00292 
00293 /* the 'eliminate the decode tree' optimization actually requires the
00294    codewords to be MSb first, not LSb.  This is an annoying inelegancy
00295    (and one of the first places where carefully thought out design
00296    turned out to be wrong; Vorbis II and future Ogg codecs should go
00297    to an MSb bitpacker), but not actually the huge hit it appears to
00298    be.  The first-stage decode table catches most words so that
00299    bitreverse is not in the main execution path. */
00300 
00301 static ogg_uint32_t bitreverse(ogg_uint32_t x){
00302   x=    ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
00303   x=    ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
00304   x=    ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
00305   x=    ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
00306   return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
00307 }
00308 
00309 STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){
00310   int  read=book->dec_maxlength;
00311   long lo,hi;
00312   long lok = oggpack_look(b,book->dec_firsttablen);
00313  
00314   if (lok >= 0) {
00315     long entry = book->dec_firsttable[lok];
00316     if(entry&0x80000000UL){
00317       lo=(entry>>15)&0x7fff;
00318       hi=book->used_entries-(entry&0x7fff);
00319     }else{
00320       oggpack_adv(b, book->dec_codelengths[entry-1]);
00321       return(entry-1);
00322     }
00323   }else{
00324     lo=0;
00325     hi=book->used_entries;
00326   }
00327 
00328   lok = oggpack_look(b, read);
00329 
00330   while(lok<0 && read>1)
00331     lok = oggpack_look(b, --read);
00332   if(lok<0)return -1;
00333 
00334   /* bisect search for the codeword in the ordered list */
00335   {
00336     ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
00337 
00338     while(hi-lo>1){
00339       long p=(hi-lo)>>1;
00340       long test=book->codelist[lo+p]>testword;    
00341       lo+=p&(test-1);
00342       hi-=p&(-test);
00343     }
00344 
00345     if(book->dec_codelengths[lo]<=read){
00346       oggpack_adv(b, book->dec_codelengths[lo]);
00347       return(lo);
00348     }
00349   }
00350   
00351   oggpack_adv(b, read);
00352   return(-1);
00353 }
00354 
00355 /* Decode side is specced and easier, because we don't need to find
00356    matches using different criteria; we simply read and map.  There are
00357    two things we need to do 'depending':
00358    
00359    We may need to support interleave.  We don't really, but it's
00360    convenient to do it here rather than rebuild the vector later.
00361 
00362    Cascades may be additive or multiplicitive; this is not inherent in
00363    the codebook, but set in the code using the codebook.  Like
00364    interleaving, it's easiest to do it here.  
00365    addmul==0 -> declarative (set the value)
00366    addmul==1 -> additive
00367    addmul==2 -> multiplicitive */
00368 
00369 /* returns the [original, not compacted] entry number or -1 on eof *********/
00370 long vorbis_book_decode(codebook *book, oggpack_buffer *b){
00371   long packed_entry=decode_packed_entry_number(book,b);
00372   if(packed_entry>=0)
00373     return(book->dec_index[packed_entry]);
00374   
00375   /* if there's no dec_index, the codebook unpacking isn't collapsed */
00376   return(packed_entry);
00377 }
00378 
00379 /* returns 0 on OK or -1 on eof *************************************/
00380 long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){
00381   int step=n/book->dim;
00382   //long *entry = alloca(sizeof(*entry)*step); //patch
00383   long *entry = (long*)_ogg_malloc(sizeof(*entry)*step); //patch
00384   //float **t = alloca(sizeof(*t)*step); //patch
00385   float **t = (float**)_ogg_malloc(sizeof(*t)*step);   //patch
00386   int i,j,o;
00387 
00388   for (i = 0; i < step; i++) {
00389     entry[i]=decode_packed_entry_number(book,b);
00390     if(entry[i]==-1){
00391         free(entry); //patch
00392         free(t); //patch
00393         return(-1);     
00394     }
00395     
00396     t[i] = book->valuelist+entry[i]*book->dim;
00397   }
00398   for(i=0,o=0;i<book->dim;i++,o+=step)
00399     for (j=0;j<step;j++)
00400       a[o+j]+=t[j][i];
00401       
00402   free(entry); //patch 
00403   free(t); //patch   
00404   return(0);
00405 }
00406 
00407 long vorbis_book_decodev_add(codebook *book,float *a,oggpack_buffer *b,int n){
00408   int i,j,entry;
00409   float *t;
00410 
00411   if(book->dim>8){
00412     for(i=0;i<n;){
00413       entry = decode_packed_entry_number(book,b);
00414       if(entry==-1)return(-1);
00415       t     = book->valuelist+entry*book->dim;
00416       for (j=0;j<book->dim;)
00417         a[i++]+=t[j++];
00418     }
00419   }else{
00420     for(i=0;i<n;){
00421       entry = decode_packed_entry_number(book,b);
00422       if(entry==-1)return(-1);
00423       t     = book->valuelist+entry*book->dim;
00424       j=0;
00425       switch((int)book->dim){
00426       case 8:
00427         a[i++]+=t[j++];
00428       case 7:
00429         a[i++]+=t[j++];
00430       case 6:
00431         a[i++]+=t[j++];
00432       case 5:
00433         a[i++]+=t[j++];
00434       case 4:
00435         a[i++]+=t[j++];
00436       case 3:
00437         a[i++]+=t[j++];
00438       case 2:
00439         a[i++]+=t[j++];
00440       case 1:
00441         a[i++]+=t[j++];
00442       case 0:
00443         break;
00444       }
00445     }
00446   }    
00447   return(0);
00448 }
00449 
00450 long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){
00451   int i,j,entry;
00452   float *t;
00453 
00454   for(i=0;i<n;){
00455     entry = decode_packed_entry_number(book,b);
00456     if(entry==-1)return(-1);
00457     t     = book->valuelist+entry*book->dim;
00458     for (j=0;j<book->dim;)
00459       a[i++]=t[j++];
00460   }
00461   return(0);
00462 }
00463 
00464 long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch,
00465                               oggpack_buffer *b,int n){
00466   long i,j,entry;
00467   int chptr=0;
00468 
00469   for(i=offset/ch;i<(offset+n)/ch;){
00470     entry = decode_packed_entry_number(book,b);
00471     if(entry==-1)return(-1);
00472     {
00473       const float *t = book->valuelist+entry*book->dim;
00474       for (j=0;j<book->dim;j++){
00475         a[chptr++][i]+=t[j];
00476         if(chptr==ch){
00477           chptr=0;
00478           i++;
00479         }
00480       }
00481     }
00482   }
00483   return(0);
00484 }
00485 
00486 #ifdef _V_SELFTEST
00487 /* Simple enough; pack a few candidate codebooks, unpack them.  Code a
00488    number of vectors through (keeping track of the quantized values),
00489    and decode using the unpacked book.  quantized version of in should
00490    exactly equal out */
00491 
00492 #include <stdio.h>
00493 
00494 #include "vorbis/book/lsp20_0.vqh"
00495 #include "vorbis/book/res0a_13.vqh"
00496 #define TESTSIZE 40
00497 
00498 float test1[TESTSIZE]={
00499   0.105939f,
00500   0.215373f,
00501   0.429117f,
00502   0.587974f,
00503 
00504   0.181173f,
00505   0.296583f,
00506   0.515707f,
00507   0.715261f,
00508 
00509   0.162327f,
00510   0.263834f,
00511   0.342876f,
00512   0.406025f,
00513 
00514   0.103571f,
00515   0.223561f,
00516   0.368513f,
00517   0.540313f,
00518 
00519   0.136672f,
00520   0.395882f,
00521   0.587183f,
00522   0.652476f,
00523 
00524   0.114338f,
00525   0.417300f,
00526   0.525486f,
00527   0.698679f,
00528 
00529   0.147492f,
00530   0.324481f,
00531   0.643089f,
00532   0.757582f,
00533 
00534   0.139556f,
00535   0.215795f,
00536   0.324559f,
00537   0.399387f,
00538 
00539   0.120236f,
00540   0.267420f,
00541   0.446940f,
00542   0.608760f,
00543 
00544   0.115587f,
00545   0.287234f,
00546   0.571081f,
00547   0.708603f,
00548 };
00549 
00550 float test3[TESTSIZE]={
00551   0,1,-2,3,4,-5,6,7,8,9,
00552   8,-2,7,-1,4,6,8,3,1,-9,
00553   10,11,12,13,14,15,26,17,18,19,
00554   30,-25,-30,-1,-5,-32,4,3,-2,0};
00555 
00556 static_codebook *testlist[]={&_vq_book_lsp20_0,
00557                              &_vq_book_res0a_13,NULL};
00558 float   *testvec[]={test1,test3};
00559 
00560 int main(){
00561   oggpack_buffer write;
00562   oggpack_buffer read;
00563   long ptr=0,i;
00564   oggpack_writeinit(&write);
00565   
00566   fprintf(stderr,"Testing codebook abstraction...:\n");
00567 
00568   while(testlist[ptr]){
00569     codebook c;
00570     static_codebook s;
00571     float *qv=alloca(sizeof(*qv)*TESTSIZE);
00572     float *iv=alloca(sizeof(*iv)*TESTSIZE);
00573     memcpy(qv,testvec[ptr],sizeof(*qv)*TESTSIZE);
00574     memset(iv,0,sizeof(*iv)*TESTSIZE);
00575 
00576     fprintf(stderr,"\tpacking/coding %ld... ",ptr);
00577 
00578     /* pack the codebook, write the testvector */
00579     oggpack_reset(&write);
00580     vorbis_book_init_encode(&c,testlist[ptr]); /* get it into memory
00581                                                   we can write */
00582     vorbis_staticbook_pack(testlist[ptr],&write);
00583     fprintf(stderr,"Codebook size %ld bytes... ",oggpack_bytes(&write));
00584     for(i=0;i<TESTSIZE;i+=c.dim){
00585       int best=_best(&c,qv+i,1);
00586       vorbis_book_encodev(&c,best,qv+i,&write);
00587     }
00588     vorbis_book_clear(&c);
00589     
00590     fprintf(stderr,"OK.\n");
00591     fprintf(stderr,"\tunpacking/decoding %ld... ",ptr);
00592 
00593     /* transfer the write data to a read buffer and unpack/read */
00594     oggpack_readinit(&read,oggpack_get_buffer(&write),oggpack_bytes(&write));
00595     if(vorbis_staticbook_unpack(&read,&s)){
00596       fprintf(stderr,"Error unpacking codebook.\n");
00597       exit(1);
00598     }
00599     if(vorbis_book_init_decode(&c,&s)){
00600       fprintf(stderr,"Error initializing codebook.\n");
00601       exit(1);
00602     }
00603 
00604     for(i=0;i<TESTSIZE;i+=c.dim)
00605       if(vorbis_book_decodev_set(&c,iv+i,&read,c.dim)==-1){
00606         fprintf(stderr,"Error reading codebook test data (EOP).\n");
00607         exit(1);
00608       }
00609     for(i=0;i<TESTSIZE;i++)
00610       if(fabs(qv[i]-iv[i])>.000001){
00611         fprintf(stderr,"read (%g) != written (%g) at position (%ld)\n",
00612                 iv[i],qv[i],i);
00613         exit(1);
00614       }
00615           
00616     fprintf(stderr,"OK\n");
00617     ptr++;
00618   }
00619 
00620   /* The above is the trivial stuff; now try unquantizing a log scale codebook */
00621 
00622   exit(0);
00623 }
00624 
00625 #endif

Generated by  doxygen 1.6.2