X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fcodebook.c;h=db0066c63edc667262a50b99ab72f95f935dae0c;hb=fba64f657f2653fae8045a8013f05ea1e6acc67a;hp=d55baa20aad7c7b4d80f78fe1794185729bc020d;hpb=a2350e7135bcb7042976b87610bac56c3b3ce77c;p=platform%2Fupstream%2Flibvorbis.git diff --git a/lib/codebook.c b/lib/codebook.c index d55baa2..db0066c 100644 --- a/lib/codebook.c +++ b/lib/codebook.c @@ -1,217 +1,29 @@ /******************************************************************** * * - * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY * - * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. * - * PLEASE READ THESE TERMS DISTRIBUTING. * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * - * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 * - * by Monty and The XIPHOPHORUS Company * - * http://www.xiph.org/ * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * + * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: basic codebook pack/unpack/code/decode operations - last mod: $Id: codebook.c,v 1.7 2000/02/06 13:40:39 xiphmont Exp $ + last mod: $Id$ ********************************************************************/ #include +#include #include +#include #include "vorbis/codec.h" -#include "vorbis/codebook.h" -#include "bitwise.h" -#include "bookinternal.h" - -/**** pack/unpack helpers ******************************************/ -static int ilog(unsigned int v){ - int ret=0; - while(v){ - ret++; - v>>=1; - } - return(ret); -} - -/* code that packs the 24 bit float can be found in vq/bookutil.c */ - -static double _float24_unpack(long val){ - double mant=val&0x3ffff; - double sign=val&0x800000; - double exp =(val&0x7c0000)>>18; - if(sign)mant= -mant; - return(ldexp(mant,exp-17-VQ_FEXP_BIAS)); -} - -/* given a list of word lengths, generate a list of codewords. Works - for length ordered or unordered, always assigns the lowest valued - codewords first */ -long *_make_words(long *l,long n){ - long i,j; - long marker[33]; - long *r=malloc(n*sizeof(long)); - memset(marker,0,sizeof(marker)); - - for(i=0;i>length)){ - /* error condition; the lengths must specify an overpopulated tree */ - free(r); - return(NULL); - } - r[i]=entry; - - /* Look to see if the next shorter marker points to the node - above. if so, update it and repeat. */ - { - for(j=length;j>0;j--){ - - if(marker[j]&1){ - /* have to jump branches */ - if(j==1) - marker[1]++; - else - marker[j]=marker[j-1]<<1; - break; /* invariant says next upper marker would already - have been moved if it was on the same path */ - } - marker[j]++; - } - } - - /* prune the tree; the implicit invariant says all the longer - markers were dangling from our just-taken node. Dangle them - from our *new* node. */ - for(j=length+1;j<33;j++) - marker[j]=marker[j-1]<<1; - } - - /* bitreverse the words because our bitwise packer/unpacker is LSb - endian */ - for(i=0;i>j)&1; - } - r[i]=temp; - } - - return(r); -} - -/* build the decode helper tree from the codewords */ -decode_aux *_make_decode_tree(codebook *c){ - const static_codebook *s=c->c; - long top=0,i,j; - decode_aux *t=malloc(sizeof(decode_aux)); - long *ptr0=t->ptr0=calloc(c->entries*2,sizeof(long)); - long *ptr1=t->ptr1=calloc(c->entries*2,sizeof(long)); - long *codelist=_make_words(s->lengthlist,s->entries); - - if(codelist==NULL)return(NULL); - t->aux=c->entries*2; - - for(i=0;ientries;i++){ - long ptr=0; - for(j=0;jlengthlist[i]-1;j++){ - int bit=(codelist[i]>>j)&1; - if(!bit){ - if(!ptr0[ptr]) - ptr0[ptr]= ++top; - ptr=ptr0[ptr]; - }else{ - if(!ptr1[ptr]) - ptr1[ptr]= ++top; - ptr=ptr1[ptr]; - } - } - if(!((codelist[i]>>j)&1)) - ptr0[ptr]=-i; - else - ptr1[ptr]=-i; - } - free(codelist); - return(t); -} - -/* unpack the quantized list of values for encode/decode ***********/ -static double *_book_unquantize(const static_codebook *b){ - long j,k; - double mindel=_float24_unpack(b->q_min); - double delta=_float24_unpack(b->q_delta); - double *r=malloc(sizeof(double)*b->entries*b->dim); - - for(j=0;jentries;j++){ - double last=0.; - for(k=0;kdim;k++){ - double val=b->quantlist[j*b->dim+k]*delta+last+mindel; - r[j*b->dim+k]=val; - if(b->q_sequencep)last=val; - } - } - return(r); -} - -void vorbis_staticbook_clear(static_codebook *b){ - if(b->quantlist)free(b->quantlist); - if(b->lengthlist)free(b->lengthlist); - if(b->encode_tree){ - free(b->encode_tree->ptr0); - free(b->encode_tree->ptr1); - free(b->encode_tree->p); - free(b->encode_tree->q); - memset(b->encode_tree,0,sizeof(encode_aux)); - free(b->encode_tree); - } - memset(b,0,sizeof(static_codebook)); -} - -void vorbis_book_clear(codebook *b){ - /* static book is not cleared; we're likely called on the lookup and - the static codebook belongs to the info struct */ - if(b->decode_tree){ - free(b->decode_tree->ptr0); - free(b->decode_tree->ptr1); - memset(b->decode_tree,0,sizeof(decode_aux)); - free(b->decode_tree); - } - if(b->valuelist)free(b->valuelist); - if(b->codelist)free(b->codelist); - memset(b,0,sizeof(codebook)); -} - -int vorbis_book_init_encode(codebook *c,const static_codebook *s){ - memset(c,0,sizeof(codebook)); - c->c=s; - c->entries=s->entries; - c->dim=s->dim; - c->codelist=_make_words(s->lengthlist,s->entries); - c->valuelist=_book_unquantize(s); - return(0); -} - -int vorbis_book_init_decode(codebook *c,const static_codebook *s){ - memset(c,0,sizeof(codebook)); - c->c=s; - c->entries=s->entries; - c->dim=s->dim; - c->valuelist=_book_unquantize(s); - c->decode_tree=_make_decode_tree(c); - if(c->decode_tree==NULL)goto err_out; - return(0); - err_out: - vorbis_book_clear(c); - return(-1); -} +#include "codebook.h" +#include "scales.h" +#include "misc.h" +#include "os.h" /* packs the given codebook into the bitstream **************************/ @@ -220,377 +32,453 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){ int ordered=0; /* first the basic parameters */ - _oggpack_write(opb,0x564342,24); - _oggpack_write(opb,c->dim,16); - _oggpack_write(opb,c->entries,24); + 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;ientries;i++) - if(c->lengthlist[i]lengthlist[i-1])break; + if(c->lengthlist[i-1]==0 || c->lengthlist[i]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 */ + oggpack_write(opb,1,1); /* ordered */ + oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */ for(i=1;ientries;i++){ - long this=c->lengthlist[i]; - long last=c->lengthlist[i-1]; + char this=c->lengthlist[i]; + char last=c->lengthlist[i-1]; if(this>last){ - for(j=last;jentries-count)); - count=i; - } + for(j=last;jentries-count)); + count=i; + } } } - _oggpack_write(opb,i-count,ilog(c->entries-count)); + 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 */ + 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;ientries;i++) - _oggpack_write(opb,c->lengthlist[i]-1,5); + if(c->lengthlist[i]==0)break; + + if(i==c->entries){ + oggpack_write(opb,0,1); /* no unused entries */ + for(i=0;ientries;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;ientries;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(c->quantlist){ - /* we have a mapping. bundle it out. */ - _oggpack_write(opb,1,1); + 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,24); - _oggpack_write(opb,c->q_delta,24); - _oggpack_write(opb,c->q_quant-1,4); - _oggpack_write(opb,c->q_sequencep,1); + 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); - /* quantized values */ - for(i=0;ientries*c->dim;i++) - _oggpack_write(opb,c->quantlist[i],c->q_quant); + { + 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; + } - }else{ - /* no mapping. */ - _oggpack_write(opb,0,1); + /* quantized values */ + for(i=0;iquantlist[i]),c->q_quant); + + } + break; + default: + /* error case; we don't have any other map types now */ + return(-1); } - + return(0); } /* unpacks a codebook from the packet buffer into the codebook struct, readies the codebook auxiliary structures for decode *************/ -int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){ +static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){ long i,j; - memset(s,0,sizeof(static_codebook)); + static_codebook *s=_ogg_calloc(1,sizeof(*s)); + s->allocedp=1; /* make sure alignment is correct */ - if(_oggpack_read(opb,24)!=0x564342)goto _eofout; + if(oggpack_read(opb,24)!=0x564342)goto _eofout; /* first the basic parameters */ - s->dim=_oggpack_read(opb,16); - s->entries=_oggpack_read(opb,24); + s->dim=oggpack_read(opb,16); + s->entries=oggpack_read(opb,24); if(s->entries==-1)goto _eofout; + if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout; + /* codeword ordering.... length ordered or unordered? */ - switch(_oggpack_read(opb,1)){ - case 0: + switch((int)oggpack_read(opb,1)){ + case 0:{ + long unused; + /* allocated but unused entries? */ + unused=oggpack_read(opb,1); + if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb)) + goto _eofout; /* unordered */ - s->lengthlist=malloc(sizeof(long)*s->entries); - for(i=0;ientries;i++){ - long num=_oggpack_read(opb,5); - if(num==-1)goto _eofout; - s->lengthlist[i]=num+1; + s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries); + + /* allocated but unused entries? */ + if(unused){ + /* yes, unused entries */ + + for(i=0;ientries;i++){ + if(oggpack_read(opb,1)){ + 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;ientries;i++){ + long num=oggpack_read(opb,5); + if(num==-1)goto _eofout; + s->lengthlist[i]=num+1; + } } - + break; + } case 1: /* ordered */ { - long length=_oggpack_read(opb,5)+1; - s->lengthlist=malloc(sizeof(long)*s->entries); - + long length=oggpack_read(opb,5)+1; + if(length==0)goto _eofout; + s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries); + for(i=0;ientries;){ - long num=_oggpack_read(opb,ilog(s->entries-i)); - if(num==-1)goto _eofout; - for(j=0;jlengthlist[i]=length; - length++; + long num=oggpack_read(opb,_ilog(s->entries-i)); + if(num==-1)goto _eofout; + if(length>32 || num>s->entries-i || + (num>0 && (num-1)>>(length-1)>1)){ + goto _errout; + } + if(length>32)goto _errout; + for(j=0;jlengthlist[i]=length; + length++; } } break; default: /* EOF */ - return(-1); + goto _eofout; } - + /* Do we have a mapping to unpack? */ - if(_oggpack_read(opb,1)){ + switch((s->maptype=oggpack_read(opb,4))){ + case 0: + /* no mapping */ + break; + case 1: case 2: + /* implicitly populated value mapping */ + /* explicitly populated value mapping */ - /* values that define the dequantization */ - s->q_min=_oggpack_read(opb,24); - s->q_delta=_oggpack_read(opb,24); - s->q_quant=_oggpack_read(opb,4)+1; - s->q_sequencep=_oggpack_read(opb,1); - - /* quantized values */ - s->quantlist=malloc(sizeof(double)*s->entries*s->dim); - for(i=0;ientries*s->dim;i++) - s->quantlist[i]=_oggpack_read(opb,s->q_quant); - if(s->quantlist[i-1]==-1)goto _eofout; + s->q_min=oggpack_read(opb,32); + s->q_delta=oggpack_read(opb,32); + s->q_quant=oggpack_read(opb,4)+1; + s->q_sequencep=oggpack_read(opb,1); + if(s->q_sequencep==-1)goto _eofout; + + { + int quantvals=0; + switch(s->maptype){ + case 1: + quantvals=(s->dim==0?0:_book_maptype1_quantvals(s)); + break; + case 2: + quantvals=s->entries*s->dim; + break; + } + + /* quantized values */ + if(((quantvals*s->q_quant+7)>>3)>opb->storage-oggpack_bytes(opb)) + goto _eofout; + s->quantlist=_ogg_malloc(sizeof(*s->quantlist)*quantvals); + for(i=0;iquantlist[i]=oggpack_read(opb,s->q_quant); + + if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout; + } + break; + default: + goto _errout; } /* all set */ - return(0); + return(s); _errout: _eofout: - vorbis_staticbook_clear(s); - return(-1); + vorbis_staticbook_destroy(s); + return(NULL); } -/* returns the number of bits ***************************************/ +/* returns the number of bits ************************************************/ int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){ - _oggpack_write(b,book->codelist[a],book->c->lengthlist[a]); + if(a<0 || a>=book->c->entries)return(0); + oggpack_write(b,book->codelist[a],book->c->lengthlist[a]); return(book->c->lengthlist[a]); } -/* returns the number of bits and *modifies a* to the residual error *****/ -int vorbis_book_encodev(codebook *book, double *a, oggpack_buffer *b){ - encode_aux *t=book->c->encode_tree; - int dim=book->dim; - int ptr=0,k; - - while(1){ - double c=0.; - double *p=book->valuelist+t->p[ptr]; - double *q=book->valuelist+t->q[ptr]; - - for(k=0;k0.) /* in A */ - ptr= -t->ptr0[ptr]; - else /* in B */ - ptr= -t->ptr1[ptr]; - if(ptr<=0)break; +/* the 'eliminate the decode tree' optimization actually requires the + codewords to be MSb first, not LSb. This is an annoying inelegancy + (and one of the first places where carefully thought out design + turned out to be wrong; Vorbis II and future Ogg codecs should go + to an MSb bitpacker), but not actually the huge hit it appears to + be. The first-stage decode table catches most words so that + bitreverse is not in the main execution path. */ + +static ogg_uint32_t bitreverse(ogg_uint32_t x){ + x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000); + x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00); + x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0); + x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc); + return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa); +} + +STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){ + int read=book->dec_maxlength; + long lo,hi; + long lok = oggpack_look(b,book->dec_firsttablen); + + if (lok >= 0) { + long entry = book->dec_firsttable[lok]; + if(entry&0x80000000UL){ + lo=(entry>>15)&0x7fff; + hi=book->used_entries-(entry&0x7fff); + }else{ + oggpack_adv(b, book->dec_codelengths[entry-1]); + return(entry-1); + } + }else{ + lo=0; + hi=book->used_entries; + } + + lok = oggpack_look(b, read); + + while(lok<0 && read>1) + lok = oggpack_look(b, --read); + if(lok<0)return -1; + + /* bisect search for the codeword in the ordered list */ + { + ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok); + + while(hi-lo>1){ + long p=(hi-lo)>>1; + long test=book->codelist[lo+p]>testword; + lo+=p&(test-1); + hi-=p&(-test); + } + + if(book->dec_codelengths[lo]<=read){ + oggpack_adv(b, book->dec_codelengths[lo]); + return(lo); + } } - for(k=0;kvaluelist-ptr*dim)[k]; - return(vorbis_book_encode(book,-ptr,b)); + + oggpack_adv(b, read); + + return(-1); } -/* returns the entry number or -1 on eof ****************************/ +/* Decode side is specced and easier, because we don't need to find + matches using different criteria; we simply read and map. There are + two things we need to do 'depending': + + We may need to support interleave. We don't really, but it's + convenient to do it here rather than rebuild the vector later. + + Cascades may be additive or multiplicitive; this is not inherent in + the codebook, but set in the code using the codebook. Like + interleaving, it's easiest to do it here. + addmul==0 -> declarative (set the value) + addmul==1 -> additive + addmul==2 -> multiplicitive */ + +/* returns the [original, not compacted] entry number or -1 on eof *********/ long vorbis_book_decode(codebook *book, oggpack_buffer *b){ - long ptr=0; - decode_aux *t=book->decode_tree; - do{ - switch(_oggpack_read1(b)){ - case 0: - ptr=t->ptr0[ptr]; - break; - case 1: - ptr=t->ptr1[ptr]; - break; - case -1: - return(-1); + if(book->used_entries>0){ + long packed_entry=decode_packed_entry_number(book,b); + if(packed_entry>=0) + return(book->dec_index[packed_entry]); + } + + /* if there's no dec_index, the codebook unpacking isn't collapsed */ + return(-1); +} + +/* returns 0 on OK or -1 on eof *************************************/ +/* decode vector / dim granularity gaurding is done in the upper layer */ +long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){ + if(book->used_entries>0){ + int step=n/book->dim; + long *entry = alloca(sizeof(*entry)*step); + float **t = alloca(sizeof(*t)*step); + int i,j,o; + + for (i = 0; i < step; i++) { + entry[i]=decode_packed_entry_number(book,b); + if(entry[i]==-1)return(-1); + t[i] = book->valuelist+entry[i]*book->dim; } - }while(ptr>0); - return(-ptr); + for(i=0,o=0;idim;i++,o+=step) + for (j=0;jdim;i++)a[i]+=(book->valuelist+entry*book->dim)[i]; - return(entry); +/* decode vector / dim granularity gaurding is done in the upper layer */ +long vorbis_book_decodev_add(codebook *book,float *a,oggpack_buffer *b,int n){ + if(book->used_entries>0){ + int i,j,entry; + float *t; + + if(book->dim>8){ + for(i=0;ivaluelist+entry*book->dim; + for (j=0;jdim;) + a[i++]+=t[j++]; + } + }else{ + for(i=0;ivaluelist+entry*book->dim; + j=0; + switch((int)book->dim){ + case 8: + a[i++]+=t[j++]; + case 7: + a[i++]+=t[j++]; + case 6: + a[i++]+=t[j++]; + case 5: + a[i++]+=t[j++]; + case 4: + a[i++]+=t[j++]; + case 3: + a[i++]+=t[j++]; + case 2: + a[i++]+=t[j++]; + case 1: + a[i++]+=t[j++]; + case 0: + break; + } + } + } + } + return(0); } -#ifdef _V_SELFTEST - -/* Simple enough; pack a few candidate codebooks, unpack them. Code a - number of vectors through (keeping track of the quantized values), - and decode using the unpacked book. quantized version of in should - exactly equal out */ - -#include -#include "vorbis/book/lsp20_0.vqh" -#include "vorbis/book/lsp32_0.vqh" -#define TESTSIZE 40 -#define TESTDIM 4 - -double test1[40]={ - 0.105939, - 0.215373, - 0.429117, - 0.587974, - - 0.181173, - 0.296583, - 0.515707, - 0.715261, - - 0.162327, - 0.263834, - 0.342876, - 0.406025, - - 0.103571, - 0.223561, - 0.368513, - 0.540313, - - 0.136672, - 0.395882, - 0.587183, - 0.652476, - - 0.114338, - 0.417300, - 0.525486, - 0.698679, - - 0.147492, - 0.324481, - 0.643089, - 0.757582, - - 0.139556, - 0.215795, - 0.324559, - 0.399387, - - 0.120236, - 0.267420, - 0.446940, - 0.608760, - - 0.115587, - 0.287234, - 0.571081, - 0.708603, -}; - -double test2[40]={ - 0.088654, - 0.165742, - 0.279013, - 0.395894, - - 0.110812, - 0.218422, - 0.283423, - 0.371719, - - 0.136985, - 0.186066, - 0.309814, - 0.381521, - - 0.123925, - 0.211707, - 0.314771, - 0.433026, - - 0.088619, - 0.192276, - 0.277568, - 0.343509, - - 0.068400, - 0.132901, - 0.223999, - 0.302538, - - 0.202159, - 0.306131, - 0.360362, - 0.416066, - - 0.072591, - 0.178019, - 0.304315, - 0.376516, - - 0.094336, - 0.188401, - 0.325119, - 0.390264, - - 0.091636, - 0.223099, - 0.282899, - 0.375124, -}; - -static_codebook *testlist[]={&_vq_book_lsp20_0,&_vq_book_lsp32_0,NULL}; -double *testvec[]={test1,test2}; - -int main(){ - oggpack_buffer write; - oggpack_buffer read; - long ptr=0,i; - _oggpack_writeinit(&write); - - fprintf(stderr,"Testing codebook abstraction...:\n"); - - while(testlist[ptr]){ - codebook c; - static_codebook s; - double *qv=alloca(sizeof(double)*TESTSIZE); - double *iv=alloca(sizeof(double)*TESTSIZE); - memcpy(qv,testvec[ptr],sizeof(double)*TESTSIZE); - memset(iv,0,sizeof(double)*TESTSIZE); - - fprintf(stderr,"\tpacking/coding %ld... ",ptr); - - /* pack the codebook, write the testvector */ - _oggpack_reset(&write); - vorbis_book_init_encode(&c,testlist[ptr]); /* get it into memory - we can write */ - vorbis_staticbook_pack(testlist[ptr],&write); - fprintf(stderr,"Codebook size %ld bytes... ",_oggpack_bytes(&write)); - for(i=0;i internally rather than in the upper layer (called only by + floor0) */ +long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){ + if(book->used_entries>0){ + int i,j,entry; + float *t; + + for(i=0;ivaluelist+entry*book->dim; + for (j=0;idim;){ + a[i++]=t[j++]; + } } - if(vorbis_book_init_decode(&c,&s)){ - fprintf(stderr,"Error initializing codebook.\n"); - exit(1); + }else{ + int i; + + for(i=0;i.000001){ - fprintf(stderr,"input (%g) != output (%g) at position (%ld)\n", - iv[i],testvec[ptr][i]-qv[i],i); - exit(1); +long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch, + oggpack_buffer *b,int n){ + + long i,j,entry; + int chptr=0; + if(book->used_entries>0){ + for(i=offset/ch;i<(offset+n)/ch;){ + entry = decode_packed_entry_number(book,b); + if(entry==-1)return(-1); + { + const float *t = book->valuelist+entry*book->dim; + for (j=0;jdim;j++){ + a[chptr++][i]+=t[j]; + if(chptr==ch){ + chptr=0; + i++; + } + } } - - fprintf(stderr,"OK\n"); - ptr++; + } } - exit(0); + return(0); } - -#endif