00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00029
00030 int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
00031 long i,j;
00032 int ordered=0;
00033
00034
00035 oggpack_write(opb,0x564342,24);
00036 oggpack_write(opb,c->dim,16);
00037 oggpack_write(opb,c->entries,24);
00038
00039
00040
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
00048
00049
00050
00051 long count=0;
00052 oggpack_write(opb,1,1);
00053 oggpack_write(opb,c->lengthlist[0]-1,5);
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
00069
00070 oggpack_write(opb,0,1);
00071
00072
00073
00074
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);
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);
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
00096
00097 oggpack_write(opb,c->maptype,4);
00098 switch(c->maptype){
00099 case 0:
00100
00101 break;
00102 case 1:case 2:
00103
00104
00105
00106 if(!c->quantlist){
00107
00108 return(-1);
00109 }
00110
00111
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
00122
00123 quantvals=_book_maptype1_quantvals(c);
00124 break;
00125 case 2:
00126
00127 quantvals=c->entries*c->dim;
00128 break;
00129 default:
00130 quantvals=-1;
00131 }
00132
00133
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
00141 return(-1);
00142 }
00143
00144 return(0);
00145 }
00146
00147
00148
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
00155 if(oggpack_read(opb,24)!=0x564342)goto _eofout;
00156
00157
00158 s->dim=oggpack_read(opb,16);
00159 s->entries=oggpack_read(opb,24);
00160 if(s->entries==-1)goto _eofout;
00161
00162
00163 switch((int)oggpack_read(opb,1)){
00164 case 0:
00165
00166 s->lengthlist=(long int*)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
00167
00168
00169 if(oggpack_read(opb,1)){
00170
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
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
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
00207 return(-1);
00208 }
00209
00210
00211 switch((s->maptype=oggpack_read(opb,4))){
00212 case 0:
00213
00214 break;
00215 case 1: case 2:
00216
00217
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
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
00248 return(0);
00249
00250 _errout:
00251 _eofout:
00252 vorbis_staticbook_clear(s);
00253 return(-1);
00254 }
00255
00256
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
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
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
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
00294
00295
00296
00297
00298
00299
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
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
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
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
00376 return(packed_entry);
00377 }
00378
00379
00380 long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){
00381 int step=n/book->dim;
00382
00383 long *entry = (long*)_ogg_malloc(sizeof(*entry)*step);
00384
00385 float **t = (float**)_ogg_malloc(sizeof(*t)*step);
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);
00392 free(t);
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);
00403 free(t);
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
00488
00489
00490
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
00579 oggpack_reset(&write);
00580 vorbis_book_init_encode(&c,testlist[ptr]);
00581
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
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
00621
00622 exit(0);
00623 }
00624
00625 #endif