123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560 |
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <ogg/ogg.h>
- #include "vorbis/codec.h"
- #include "vorbis/codebook.h"
- #include "scales.h"
- #include "sharedbook.h"
- #include "bookinternal.h"
- #include "misc.h"
- #include "os.h"
- int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
- long i,j;
- int ordered=0;
-
- oggpack_write(opb,0x564342,24);
- oggpack_write(opb,c->dim,16);
- oggpack_write(opb,c->entries,24);
-
-
- for(i=1;i<c->entries;i++)
- if(c->lengthlist[i]<c->lengthlist[i-1])break;
- if(i==c->entries)ordered=1;
-
- if(ordered){
-
- long count=0;
- oggpack_write(opb,1,1);
- oggpack_write(opb,c->lengthlist[0]-1,5);
- for(i=1;i<c->entries;i++){
- long this=c->lengthlist[i];
- long last=c->lengthlist[i-1];
- if(this>last){
- for(j=last;j<this;j++){
- oggpack_write(opb,i-count,_ilog(c->entries-count));
- count=i;
- }
- }
- }
- oggpack_write(opb,i-count,_ilog(c->entries-count));
-
- }else{
-
- oggpack_write(opb,0,1);
-
-
- for(i=0;i<c->entries;i++)
- if(c->lengthlist[i]==0)break;
- if(i==c->entries){
- oggpack_write(opb,0,1);
- for(i=0;i<c->entries;i++)
- oggpack_write(opb,c->lengthlist[i]-1,5);
- }else{
- oggpack_write(opb,1,1);
- 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);
- }
- }
- }
- }
-
- oggpack_write(opb,c->maptype,4);
- switch(c->maptype){
- case 0:
-
- break;
- case 1:case 2:
-
-
-
- if(!c->quantlist){
-
- return(-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);
-
- {
- int quantvals;
- switch(c->maptype){
- case 1:
-
- quantvals=_book_maptype1_quantvals(c);
- break;
- case 2:
-
- quantvals=c->entries*c->dim;
- break;
- }
-
- for(i=0;i<quantvals;i++)
- oggpack_write(opb,labs(c->quantlist[i]),c->q_quant);
- }
- break;
- default:
-
- return(-1);
- }
- return(0);
- }
- int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
- long i,j;
- memset(s,0,sizeof(static_codebook));
-
- if(oggpack_read(opb,24)!=0x564342)goto _eofout;
-
- s->dim=oggpack_read(opb,16);
- s->entries=oggpack_read(opb,24);
- if(s->entries==-1)goto _eofout;
-
- switch(oggpack_read(opb,1)){
- case 0:
-
- s->lengthlist=malloc(sizeof(long)*s->entries);
-
- if(oggpack_read(opb,1)){
-
- for(i=0;i<s->entries;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{
-
- for(i=0;i<s->entries;i++){
- long num=oggpack_read(opb,5);
- if(num==-1)goto _eofout;
- s->lengthlist[i]=num+1;
- }
- }
-
- break;
- case 1:
-
- {
- long length=oggpack_read(opb,5)+1;
- s->lengthlist=malloc(sizeof(long)*s->entries);
- for(i=0;i<s->entries;){
- long num=oggpack_read(opb,_ilog(s->entries-i));
- if(num==-1)goto _eofout;
- for(j=0;j<num;j++,i++)
- s->lengthlist[i]=length;
- length++;
- }
- }
- break;
- default:
-
- return(-1);
- }
-
-
- switch((s->maptype=oggpack_read(opb,4))){
- case 0:
-
- break;
- case 1: case 2:
-
-
- 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);
- {
- int quantvals;
- switch(s->maptype){
- case 1:
- quantvals=_book_maptype1_quantvals(s);
- break;
- case 2:
- quantvals=s->entries*s->dim;
- break;
- }
-
-
- s->quantlist=malloc(sizeof(float)*quantvals);
- for(i=0;i<quantvals;i++)
- s->quantlist[i]=oggpack_read(opb,s->q_quant);
-
- if(s->quantlist[quantvals-1]==-1)goto _eofout;
- }
- break;
- default:
- goto _errout;
- }
-
- return(0);
-
- _errout:
- _eofout:
- vorbis_staticbook_clear(s);
- return(-1);
- }
- int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){
- oggpack_write(b,book->codelist[a],book->c->lengthlist[a]);
- return(book->c->lengthlist[a]);
- }
- int vorbis_book_errorv(codebook *book,float *a){
- int dim=book->dim,k;
- int best=_best(book,a,1);
- for(k=0;k<dim;k++)
- a[k]=(book->valuelist+best*dim)[k];
- return(best);
- }
- int vorbis_book_encodev(codebook *book,int best,float *a,oggpack_buffer *b){
- int k,dim=book->dim;
- for(k=0;k<dim;k++)
- a[k]=(book->valuelist+best*dim)[k];
- return(vorbis_book_encode(book,best,b));
- }
- int vorbis_book_encodevs(codebook *book,float *a,oggpack_buffer *b,
- int step,int addmul){
- int best=vorbis_book_besterror(book,a,step,addmul);
- return(vorbis_book_encode(book,best,b));
- }
- long vorbis_book_decode(codebook *book, oggpack_buffer *b){
- long ptr=0;
- decode_aux *t=book->decode_tree;
- int lok = oggpack_look(b, t->tabn);
- if (lok >= 0) {
- ptr = t->tab[lok];
- oggpack_adv(b, t->tabl[lok]);
- if (ptr <= 0)
- return -ptr;
- }
- do{
- switch(oggpack_read1(b)){
- case 0:
- ptr=t->ptr0[ptr];
- break;
- case 1:
- ptr=t->ptr1[ptr];
- break;
- case -1:
- return(-1);
- }
- }while(ptr>0);
- return(-ptr);
- }
- long vorbis_book_decodevs(codebook *book,float *a,oggpack_buffer *b,
- int step,int addmul){
- long entry=vorbis_book_decode(book,b);
- int i,o;
- float *t;
- if(entry==-1)return(-1);
- t = book->valuelist+entry*book->dim;
- switch(addmul){
- case -1:
- for(i=0,o=0;i<book->dim-3;i+=4,o+=4*step) {
- a[o]=t[i];
- a[o+step]=t[i+1];
- a[o+2*step]=t[i+2];
- a[o+3*step]=t[i+3];
- }
- for(;i<book->dim;i++,o+=step)
- a[o]=t[i];
- break;
- case 0:
- for(i=0,o=0;i<book->dim-3;i+=4,o+=4*step) {
- a[o]+=t[i];
- a[o+step]+=t[i+1];
- a[o+2*step]+=t[i+2];
- a[o+3*step]+=t[i+3];
- }
- for(;i<book->dim;i++,o+=step)
- a[o]+=t[i];
- break;
- case 1:
- for(i=0,o=0;i<book->dim-3;i+=4,o+=4*step) {
- a[o]*=t[i];
- a[o+step]*=t[i+1];
- a[o+2*step]*=t[i+2];
- a[o+3*step]*=t[i+3];
- }
- for(;i<book->dim;i++,o+=step)
- a[o]*=t[i];
- break;
- }
- return(entry);
- }
- long s_vorbis_book_decodevs(codebook *book,float *a,oggpack_buffer *b,
- int step,int addmul){
- long entry[step];
- float *t[step];
- int i,j,o;
- for (i = 0; i < step; i++) {
- entry[i]=vorbis_book_decode(book,b);
- if(entry[i]==-1)return(-1);
- t[i] = book->valuelist+entry[i]*book->dim;
- }
- switch(addmul){
- case -1:
- for(i=0,o=0;i<book->dim;i++,o+=step)
- for (j=0;j<step;j++)
- a[o+j]=t[j][i];
- break;
- case 0:
- for(i=0,o=0;i<book->dim;i++,o+=step)
- for (j=0;j<step;j++)
- a[o+j]+=t[j][i];
- break;
- case 1:
- for(i=0,o=0;i<book->dim;i++,o+=step)
- for (j=0;j<step;j++)
- a[o+j]*=t[j][i];
- break;
- }
- return(0);
- }
- #ifdef _V_SELFTEST
- #include <stdio.h>
- #include "vorbis/book/lsp20_0.vqh"
- #include "vorbis/book/res0a_13.vqh"
- #define TESTSIZE 40
- float test1[TESTSIZE]={
- 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,
- };
- float test3[TESTSIZE]={
- 0,1,-2,3,4,-5,6,7,8,9,
- 8,-2,7,-1,4,6,8,3,1,-9,
- 10,11,12,13,14,15,26,17,18,19,
- 30,-25,-30,-1,-5,-32,4,3,-2,0};
- static_codebook *testlist[]={&_vq_book_lsp20_0,
- &_vq_book_res0a_13,NULL};
- float *testvec[]={test1,test3};
- 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;
- float *qv=alloca(sizeof(float)*TESTSIZE);
- float *iv=alloca(sizeof(float)*TESTSIZE);
- memcpy(qv,testvec[ptr],sizeof(float)*TESTSIZE);
- memset(iv,0,sizeof(float)*TESTSIZE);
- fprintf(stderr,"\tpacking/coding %ld... ",ptr);
-
- oggpack_reset(&write);
- vorbis_book_init_encode(&c,testlist[ptr]);
- vorbis_staticbook_pack(testlist[ptr],&write);
- fprintf(stderr,"Codebook size %ld bytes... ",oggpack_bytes(&write));
- for(i=0;i<TESTSIZE;i+=c.dim){
- int best=_best(&c,qv+i,1);
- vorbis_book_encodev(&c,best,qv+i,&write);
- }
- vorbis_book_clear(&c);
-
- fprintf(stderr,"OK.\n");
- fprintf(stderr,"\tunpacking/decoding %ld... ",ptr);
-
- oggpack_readinit(&read,oggpack_get_buffer(&write),oggpack_bytes(&write));
- if(vorbis_staticbook_unpack(&read,&s)){
- fprintf(stderr,"Error unpacking codebook.\n");
- exit(1);
- }
- if(vorbis_book_init_decode(&c,&s)){
- fprintf(stderr,"Error initializing codebook.\n");
- exit(1);
- }
- for(i=0;i<TESTSIZE;i+=c.dim)
- if(vorbis_book_decodevs(&c,iv+i,&read,1,-1)==-1){
- fprintf(stderr,"Error reading codebook test data (EOP).\n");
- exit(1);
- }
- for(i=0;i<TESTSIZE;i++)
- if(fabs(qv[i]-iv[i])>.000001){
- fprintf(stderr,"read (%g) != written (%g) at position (%ld)\n",
- iv[i],qv[i],i);
- exit(1);
- }
-
- fprintf(stderr,"OK\n");
- ptr++;
- }
-
- exit(0);
- }
- #endif
|