1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
9 * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: basic codebook pack/unpack/code/decode operations
15 last mod: $Id: codebook.c,v 1.3 2000/01/22 13:28:17 xiphmont Exp $
17 ********************************************************************/
21 #include "vorbis/codec.h"
22 #include "vorbis/codebook.h"
24 #include "bookinternal.h"
26 /**** pack/unpack helpers ******************************************/
27 static int ilog(unsigned int v){
36 static long _float24_pack(double val){
44 exp= floor(log(val)/log(2));
45 mant=rint(ldexp(val,17-exp));
46 exp=(exp+VQ_FEXP_BIAS)<<18;
48 return(sign|exp|mant);
51 static double _float24_unpack(long val){
52 double mant=val&0x3ffff;
53 double sign=val&0x800000;
54 double exp =(val&0x7c0000)>>18;
56 return(ldexp(mant,exp-17-VQ_FEXP_BIAS));
59 /* given a list of word lengths, generate a list of codewords. Works
60 for length ordered or unordered, always assigns the lowest valued
62 long *_make_words(long *l,long n){
65 long *r=malloc(n*sizeof(long));
66 memset(marker,0,sizeof(marker));
70 long entry=marker[l[i]];
72 /* when we claim a node for an entry, we also claim the nodes
73 below it (pruning off the imagined tree that may have dangled
74 from it) as well as blocking the use of any nodes directly
78 if(length<32 && (entry>>length)){
79 /* error condition; the lengths must specify an overpopulated tree */
85 /* Look to see if the next shorter marker points to the node
86 above. if so, update it and repeat. */
88 for(j=length;j>0;j--){
91 /* have to jump branches */
95 marker[j]=marker[j-1]<<1;
96 break; /* invariant says next upper marker would already
97 have been moved if it was on the same path */
103 /* prune the tree; the implicit invariant says all the longer
104 markers were dangling from our just-taken node. Dangle them
105 from our *new* node. */
106 for(j=length+1;j<33;j++)
107 marker[j]=marker[j-1]<<1;
110 /* bitreverse the words because our bitwise packer/unpacker is LSb
124 /* unpack the quantized list of values for encode/decode ***********/
125 static double *_book_unquantize(static_codebook *b){
127 double mindel=_float24_unpack(b->q_min);
128 double delta=_float24_unpack(b->q_delta);
129 double *r=malloc(sizeof(double)*b->entries*b->dim);
131 for(j=0;j<b->entries;j++){
133 for(k=0;k<b->dim;k++){
134 double val=b->quantlist[j*b->dim+k]*delta+last+mindel;
136 if(b->q_sequencep)last=val;
142 void vorbis_book_clear(codebook *b){
143 /* static book is not cleared. It exists only in encode */
145 free(b->decode_tree->ptr0);
146 free(b->decode_tree->ptr1);
147 memset(b->decode_tree,0,sizeof(decode_aux));
148 free(b->decode_tree);
150 if(b->valuelist)free(b->valuelist);
151 if(b->codelist)free(b->codelist);
152 memset(b,0,sizeof(codebook));
155 int vorbis_book_finish(codebook *c, static_codebook *s){
156 memset(c,0,sizeof(codebook));
158 c->elements=s->elements;
160 c->codelist=_make_words(c->lengthlist,c->entries);
161 c->valuelist=_book_unquantize(c);
165 /* packs the given codebook into the bitstream **************************/
167 int vorbis_book_pack(static_codebook *c,oggpack_buffer *opb){
171 /* first the basic parameters */
172 _oggpack_write(opb,0x564342,24);
173 _oggpack_write(opb,c->dim,16);
174 _oggpack_write(opb,c->entries,24);
176 /* pack the codewords. There are two packings; length ordered and
177 length random. Decide between the two now. */
179 for(i=1;i<c->entries;i++)
180 if(c->lengthlist[i]<c->lengthlist[i-1])break;
181 if(i==c->entries)ordered=1;
184 /* length ordered. We only need to say how many codewords of
185 each length. The actual codewords are generated
189 _oggpack_write(opb,1,1); /* ordered */
190 _oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */
192 for(i=1;i<c->entries;i++){
193 long this=c->lengthlist[i];
194 long last=c->lengthlist[i-1];
196 for(j=last;j<this;j++){
197 _oggpack_write(opb,i-count,ilog(c->entries-count));
202 _oggpack_write(opb,i-count,ilog(c->entries-count));
205 /* length random. Again, we don't code the codeword itself, just
206 the length. This time, though, we have to encode each length */
207 _oggpack_write(opb,0,1); /* unordered */
208 for(i=0;i<c->entries;i++)
209 _oggpack_write(opb,c->lengthlist[i]-1,5);
212 /* is the entry number the desired return value, or do we have a
215 /* we have a mapping. bundle it out. */
216 _oggpack_write(opb,1,1);
218 /* values that define the dequantization */
219 _oggpack_write(opb,c->q_min,24);
220 _oggpack_write(opb,c->q_delta,24);
221 _oggpack_write(opb,c->q_quant-1,4);
222 _oggpack_write(opb,c->q_sequencep,1);
224 /* quantized values */
225 for(i=0;i<c->entries*c->dim;i++)
226 _oggpack_write(opb,c->quantlist[i],c->q_quant);
230 _oggpack_write(opb,0,1);
236 /* unpacks a codebook from the packet buffer into the codebook struct,
237 readies the codebook auxiliary structures for decode *************/
238 int vorbis_book_unpack(oggpack_buffer *opb,codebook *c){
240 long *lengthlist=NULL;
243 memset(c,0,sizeof(codebook));
244 memset(&s,0,sizeof(s));
246 /* make sure alignment is correct */
247 if(_oggpack_read(opb,24)!=0x564342)goto _eofout;
249 /* first the basic parameters */
250 c->dim=_oggpack_read(opb,16);
251 c->entries=_oggpack_read(opb,24);
252 if(c->entries==-1)goto _eofout;
254 /* codeword ordering.... length ordered or unordered? */
255 switch(_oggpack_read(opb,1)){
258 lengthlist=malloc(sizeof(long)*c->entries);
259 for(i=0;i<c->entries;i++){
260 long num=_oggpack_read(opb,5);
261 if(num==-1)goto _eofout;
269 long length=_oggpack_read(opb,5)+1;
270 lengthlist=malloc(sizeof(long)*c->entries);
272 for(i=0;i<c->entries;){
273 long num=_oggpack_read(opb,ilog(c->entries-i));
274 if(num==-1)goto _eofout;
275 for(j=0;j<num;j++,i++)
276 lengthlist[i]=length;
286 /* now we generate the codewords for the given lengths */
287 codelist=_make_words(c->lengthlist,c->entries);
288 if(codelist==NULL)goto _errout;
290 /* ...and the decode helper tree from the codewords */
293 decode_aux *t=c->decode_tree=malloc(sizeof(decode_aux));
294 long *ptr0=t->ptr0=calloc(c->entries*2,sizeof(long));
295 long *ptr1=t->ptr1=calloc(c->entries*2,sizeof(long));
298 for(i=0;i<c->entries;i++){
300 for(j=0;j<lengthlist[i]-1;j++){
301 int bit=(codelist[i]>>j)&1;
312 if(!((codelist[i]>>j)&1))
318 /* no longer needed */
322 /* Do we have a mapping to unpack? */
323 if(_oggpack_read(opb,1)){
325 /* values that define the dequantization */
326 s.q_min=_oggpack_read(opb,24);
327 s.q_delta=_oggpack_read(opb,24);
328 s.q_quant=_oggpack_read(opb,4)+1;
329 s.q_sequencep=_oggpack_read(opb,1);
331 s.entries=c->entries;
333 /* quantized values */
334 s.quantlist=malloc(sizeof(double)*c->entries*c->dim);
335 for(i=0;i<c->entries*c->dim;i++)
336 s.quantlist[i]=_oggpack_read(opb,s.q_quant);
337 if(s.quantlist[i-1]==-1)goto _eofout;
338 c->valuelist=_book_unquantize(&s);
339 free(s.quantlist);memset(&s,0,sizeof(s));
347 if(lengthlist)free(lengthlist);
348 if(s.quantlist)free(s.quantlist);
349 if(codelist)free(codelist);
350 vorbis_book_clear(c);
355 /* returns the number of bits ***************************************/
356 int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){
357 _oggpack_write(b,book->codelist[a],book->c->lengthlist[a]);
358 return(book->c->lengthlist[a]);
361 /* returns the number of bits and *modifies a* to the entry value *****/
362 int vorbis_book_encodev(codebook *book, double *a, oggpack_buffer *b){
363 encode_aux *t=book->c->encode_tree;
369 double *p=book->valuelist+t->p[ptr];
370 double *q=book->valuelist+t->q[ptr];
373 c+=(p[k]-q[k])*(a[k]-(p[k]+q[k])*.5);
381 memcpy(a,book->valuelist-ptr*dim,dim*sizeof(double));
382 return(vorbis_book_encode(book,-ptr,b));
385 /* returns the entry number or -1 on eof ****************************/
386 long vorbis_book_decode(codebook *book, oggpack_buffer *b){
388 decode_aux *t=book->decode_tree;
390 switch(_oggpack_read1(b)){
404 /* returns the entry number or -1 on eof ****************************/
405 long vorbis_book_decodev(codebook *book, double *a, oggpack_buffer *b){
406 long entry=vorbis_book_decode(book,b);
407 if(entry==-1)return(-1);
408 memcpy(a,book->valuelist+entry*book->dim,sizeof(double)*book->dim);
414 /* Simple enough; pack a few candidate codebooks, unpack them. Code a
415 number of vectors through (keeping track of the quantized values),
416 and decode using the unpacked book. quantized version of in should
420 #include "vorbis/book/lsp20_0.vqh"
421 #include "vorbis/book/lsp32_0.vqh"
529 static_codebook *testlist[]={&_vq_book_lsp20_0,&_vq_book_lsp32_0,NULL};
530 double *testvec[]={test1,test2};
533 oggpack_buffer write;
536 _oggpack_writeinit(&write);
538 fprintf(stderr,"Testing codebook abstraction...:\n");
540 while(testlist[ptr]){
542 double *qv=alloca(sizeof(double)*TESTSIZE);
543 double *iv=alloca(sizeof(double)*TESTSIZE);
544 memcpy(qv,testvec[ptr],sizeof(double)*TESTSIZE);
546 fprintf(stderr,"\tpacking/coding %ld... ",ptr);
548 /* pack the codebook, write the testvector */
549 _oggpack_reset(&write);
550 vorbis_book_finish(&c,testlist[ptr]); /* get it into memory we can write */
551 vorbis_book_pack(&c,&write);
552 fprintf(stderr,"Codebook size %ld bytes... ",_oggpack_bytes(&write));
553 for(i=0;i<TESTSIZE;i+=TESTDIM)
554 vorbis_book_encodev(&c,qv+i,&write);
555 vorbis_book_clear(&c);
557 fprintf(stderr,"OK.\n");
558 fprintf(stderr,"\tunpacking/decoding %ld... ",ptr);
560 /* transfer the write data to a read buffer and unpack/read */
561 _oggpack_readinit(&read,_oggpack_buffer(&write),_oggpack_bytes(&write));
562 if(vorbis_book_unpack(&read,&c)){
563 fprintf(stderr,"Error unpacking codebook.\n");
566 for(i=0;i<TESTSIZE;i+=TESTDIM)
567 if(vorbis_book_decodev(&c,iv+i,&read)){
568 fprintf(stderr,"Error reading codebook test data (EOP).\n");
571 for(i=0;i<TESTSIZE;i++)
573 fprintf(stderr,"input (%g) != output (%g) at position (%ld)\n",
578 fprintf(stderr,"OK\n");