X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fres0.c;h=d2b29a69da90ebc4c163331512fb54ee8cba3492;hb=5cf867f4695f4955c145546b8256eccf6736307e;hp=aa38158c101e9b4441935623acd9e6437cf973d0;hpb=589e3a0cc237c437a97ae37136065bc16f3f13b7;p=platform%2Fupstream%2Flibvorbis.git diff --git a/lib/res0.c b/lib/res0.c index aa38158..d2b29a6 100644 --- a/lib/res0.c +++ b/lib/res0.c @@ -1,18 +1,17 @@ /******************************************************************** * * - * 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-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * * * ******************************************************************** - function: residue backend 0 implementation - last mod: $Id: res0.c,v 1.16 2000/08/14 21:53:49 xiphmont Exp $ + function: residue backend 0, 1 and 2 implementation + last mod: $Id: res0.c,v 1.35 2001/08/13 11:33:39 xiphmont Exp $ ********************************************************************/ @@ -25,125 +24,209 @@ #include #include #include +#include #include "vorbis/codec.h" -#include "bitwise.h" +#include "codec_internal.h" #include "registry.h" -#include "bookinternal.h" -#include "sharedbook.h" +#include "codebook.h" #include "misc.h" #include "os.h" typedef struct { vorbis_info_residue0 *info; + int map; int parts; + int stages; + codebook *fullbooks; codebook *phrasebook; codebook ***partbooks; int partvals; int **decodemap; + + long postbits; + long phrasebits; + long frames; + } vorbis_look_residue0; -void free_info(vorbis_info_residue *i){ +vorbis_info_residue *res0_copy_info(vorbis_info_residue *vr){ + vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; + vorbis_info_residue0 *ret=_ogg_malloc(sizeof(vorbis_info_residue0)); + memcpy(ret,info,sizeof(vorbis_info_residue0)); + return(ret); +} + +void res0_free_info(vorbis_info_residue *i){ if(i){ memset(i,0,sizeof(vorbis_info_residue0)); - free(i); + _ogg_free(i); } } -void free_look(vorbis_look_residue *i){ +void res0_free_look(vorbis_look_residue *i){ int j; if(i){ + vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; + + /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n", + (float)look->phrasebits/look->frames, + (float)look->postbits/look->frames, + (float)(look->postbits+look->phrasebits)/look->frames);*/ + + /*vorbis_info_residue0 *info=look->info; + + fprintf(stderr, + "%ld frames encoded in %ld phrasebits and %ld residue bits " + "(%g/frame) \n",look->frames,look->phrasebits, + look->resbitsflat, + (look->phrasebits+look->resbitsflat)/(float)look->frames); + + for(j=0;jparts;j++){ + long acc=0; + fprintf(stderr,"\t[%d] == ",j); + for(k=0;kstages;k++) + if((info->secondstages[j]>>k)&1){ + fprintf(stderr,"%ld,",look->resbits[j][k]); + acc+=look->resbits[j][k]; + } + + fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j], + acc?(float)acc/(look->resvals[j]*info->grouping):0); + } + fprintf(stderr,"\n");*/ + for(j=0;jparts;j++) - if(look->partbooks[j])free(look->partbooks[j]); - free(look->partbooks); + if(look->partbooks[j])_ogg_free(look->partbooks[j]); + _ogg_free(look->partbooks); for(j=0;jpartvals;j++) - free(look->decodemap[j]); - free(look->decodemap); + _ogg_free(look->decodemap[j]); + _ogg_free(look->decodemap); memset(i,0,sizeof(vorbis_look_residue0)); - free(i); + _ogg_free(i); + } +} + +static int ilog(unsigned int v){ + int ret=0; + while(v){ + ret++; + v>>=1; } + return(ret); } -void pack(vorbis_info_residue *vr,oggpack_buffer *opb){ +static int icount(unsigned int v){ + int ret=0; + while(v){ + ret+=v&1; + v>>=1; + } + return(ret); +} + + +void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){ vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; int j,acc=0; - _oggpack_write(opb,info->begin,24); - _oggpack_write(opb,info->end,24); + oggpack_write(opb,info->begin,24); + oggpack_write(opb,info->end,24); - _oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and + oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and code with a partitioned book */ - _oggpack_write(opb,info->partitions-1,6); /* possible partition choices */ - _oggpack_write(opb,info->groupbook,8); /* group huffman book */ + oggpack_write(opb,info->partitions-1,6); /* possible partition choices */ + oggpack_write(opb,info->groupbook,8); /* group huffman book */ + + /* secondstages is a bitmask; as encoding progresses pass by pass, a + bitmask of one indicates this partition class has bits to write + this pass */ for(j=0;jpartitions;j++){ - _oggpack_write(opb,info->secondstages[j],4); /* zero *is* a valid choice */ - acc+=info->secondstages[j]; + if(ilog(info->secondstages[j])>3){ + /* yes, this is a minor hack due to not thinking ahead */ + oggpack_write(opb,info->secondstages[j],3); + oggpack_write(opb,1,1); + oggpack_write(opb,info->secondstages[j]>>3,5); + }else + oggpack_write(opb,info->secondstages[j],4); /* trailing zero */ + acc+=icount(info->secondstages[j]); } for(j=0;jbooklist[j],8); + oggpack_write(opb,info->booklist[j],8); } /* vorbis_info is for range checking */ -vorbis_info_residue *unpack(vorbis_info *vi,oggpack_buffer *opb){ +vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ int j,acc=0; - vorbis_info_residue0 *info=calloc(1,sizeof(vorbis_info_residue0)); + vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(vorbis_info_residue0)); + codec_setup_info *ci=vi->codec_setup; + + info->begin=oggpack_read(opb,24); + info->end=oggpack_read(opb,24); + info->grouping=oggpack_read(opb,24)+1; + info->partitions=oggpack_read(opb,6)+1; + info->groupbook=oggpack_read(opb,8); - info->begin=_oggpack_read(opb,24); - info->end=_oggpack_read(opb,24); - info->grouping=_oggpack_read(opb,24)+1; - info->partitions=_oggpack_read(opb,6)+1; - info->groupbook=_oggpack_read(opb,8); for(j=0;jpartitions;j++){ - int cascade=info->secondstages[j]=_oggpack_read(opb,4); - if(cascade>1)goto errout; /* temporary! when cascading gets - reworked and actually used, we don't - want old code to DTWT */ - acc+=cascade; + int cascade=oggpack_read(opb,3); + if(oggpack_read(opb,1)) + cascade|=(oggpack_read(opb,5)<<3); + info->secondstages[j]=cascade; + + acc+=icount(cascade); } for(j=0;jbooklist[j]=_oggpack_read(opb,8); + info->booklist[j]=oggpack_read(opb,8); - if(info->groupbook>=vi->books)goto errout; + if(info->groupbook>=ci->books)goto errout; for(j=0;jbooklist[j]>=vi->books)goto errout; + if(info->booklist[j]>=ci->books)goto errout; return(info); errout: - free_info(info); + res0_free_info(info); return(NULL); } -vorbis_look_residue *look (vorbis_dsp_state *vd,vorbis_info_mode *vm, +vorbis_look_residue *res0_look (vorbis_dsp_state *vd,vorbis_info_mode *vm, vorbis_info_residue *vr){ vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; - vorbis_look_residue0 *look=calloc(1,sizeof(vorbis_look_residue0)); + vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(vorbis_look_residue0)); + backend_lookup_state *be=vd->backend_state; + int j,k,acc=0; int dim; + int maxstage=0; look->info=info; + look->map=vm->mapping; look->parts=info->partitions; - look->phrasebook=vd->fullbooks+info->groupbook; + look->fullbooks=be->fullbooks; + look->phrasebook=be->fullbooks+info->groupbook; dim=look->phrasebook->dim; - look->partbooks=calloc(look->parts,sizeof(codebook **)); + look->partbooks=_ogg_calloc(look->parts,sizeof(codebook **)); for(j=0;jparts;j++){ - int stages=info->secondstages[j]; + int stages=ilog(info->secondstages[j]); if(stages){ - look->partbooks[j]=malloc(stages*sizeof(codebook *)); + if(stages>maxstage)maxstage=stages; + look->partbooks[j]=_ogg_calloc(stages,sizeof(codebook *)); for(k=0;kpartbooks[j][k]=vd->fullbooks+info->booklist[acc++]; + if(info->secondstages[j]&(1<partbooks[j][k]=be->fullbooks+info->booklist[acc++]; } } look->partvals=rint(pow(look->parts,dim)); - look->decodemap=malloc(look->partvals*sizeof(int *)); + look->stages=maxstage; + look->decodemap=_ogg_malloc(look->partvals*sizeof(int *)); for(j=0;jpartvals;j++){ long val=j; long mult=look->partvals/look->parts; - look->decodemap[j]=malloc(dim*sizeof(int)); + look->decodemap[j]=_ogg_malloc(dim*sizeof(int)); for(k=0;kinfo; int i,j=0; - double max,localmax=0.; - double temp[128]; - double entropy[8]; + float max,localmax=0.f; + float temp[128]; + float entropy[8]; /* setup */ - for(i=0;ilocalmax)localmax=temp[i]; max=localmax; + + for(i=0;i>=1; + if(!n)break; j++; - if(n<=0)break; for(i=0;ilocalmax)localmax=temp[i]; } @@ -197,120 +282,305 @@ static int _testhack(double *vec,int n,vorbis_look_residue0 *look, return(i); } -static int _encodepart(oggpack_buffer *opb,double *vec, int n, - int stages, codebook **books){ - int i,j,bits=0; +static int _testhack(float *vec,int n,vorbis_look_residue0 *look, + int auxparts,int auxpartnum){ + vorbis_info_residue0 *info=look->info; + int i; + float max=0.f; + float temp[128]; + float entropy=0.f; - for(j=0;jdim; - int step=n/dim; - for(i=0;imax)max=temp[i]; + + for(i=0;iblimit[i] && + entropy<=info->entmax[i] && + max<=info->ampmax[i]) + break; + + return(i); +} + +static int _interleaved_encodepart(oggpack_buffer *opb,float *vec, int n, + codebook *book,vorbis_look_residue0 *look){ + int i,bits=0; + int dim=book->dim; + int step=n/dim; +#ifdef TRAIN_RESENT + char buf[80]; + FILE *f; + sprintf(buf,"res0_b%d.vqd",book-look->fullbooks); + f=fopen(buf,"a"); +#endif + + for(i=0;idim; - int step=n/dim; - for(i=0;idim; + int step=n/dim; +#ifdef TRAIN_RESENT + char buf[80]; + FILE *f; + sprintf(buf,"res0_b%d.vqd",book-look->fullbooks); + f=fopen(buf,"a"); +#endif + + for(i=0;iinfo; /* move all this setup out later */ int samples_per_partition=info->grouping; int possible_partitions=info->partitions; - int partitions_per_word=look->phrasebook->dim; int n=info->end-info->begin; - long phrasebits=0,resbitsT=0; - long *resbits=alloca(sizeof(long)*possible_partitions); - long *resvals=alloca(sizeof(long)*possible_partitions); int partvals=n/samples_per_partition; - int partwords=(partvals+partitions_per_word-1)/partitions_per_word; long **partword=_vorbis_block_alloc(vb,ch*sizeof(long *)); - partvals=partwords*partitions_per_word; - - /* we find the patition type for each partition of each + /* we find the partition type for each partition of each channel. We'll go back and do the interleaved encoding in a bit. For now, clarity */ - - memset(resbits,0,sizeof(long)*possible_partitions); - memset(resvals,0,sizeof(long)*possible_partitions); - + for(i=0;ibegin,l=0;iend;i+=samples_per_partition,l++){ + for(i=0;ibegin, + samples_per_partition,look,possible_partitions,i); + + } + +#ifdef TRAIN_RES + { + FILE *of; + char buffer[80]; + + for(i=0;imode); + of=fopen(buffer,"a"); + for(j=0;jframes++; + + return(partword); +} + +static long **_2class(vorbis_block *vb,vorbis_look_residue *vl, + float **in,int ch, + int (*classify)(float *,int,vorbis_look_residue0 *, + int,int)){ + long i,j,k,l; + vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; + vorbis_info_residue0 *info=look->info; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int possible_partitions=info->partitions; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + long **partword=_vorbis_block_alloc(vb,sizeof(long *)); + float *work=alloca(sizeof(float)*samples_per_partition); + + partword[0]=_vorbis_block_alloc(vb,n*ch/samples_per_partition*sizeof(long)); + memset(partword[0],0,n*ch/samples_per_partition*sizeof(long)); + + for(i=0,j=0,k=0,l=info->begin;i=ch){ + j=0; + l++; + } + } + partword[0][i]= + classify(work,samples_per_partition,look,possible_partitions,i); + } + +#ifdef TRAIN_RES + { + FILE *of; + char buffer[80]; + + sprintf(buffer,"resaux_%d.vqd",vb->mode); + of=fopen(buffer,"a"); + for(i=0;iframes++; + + return(partword); +} + +static int _01forward(vorbis_block *vb,vorbis_look_residue *vl, + float **in,int ch, + int pass,long **partword, + int (*encode)(oggpack_buffer *,float *,int, + codebook *,vorbis_look_residue0 *)){ + long i,j,k,s; + vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; + vorbis_info_residue0 *info=look->info; + + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int possible_partitions=info->partitions; + int partitions_per_word=look->phrasebook->dim; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + long resbits[128]; + long resvals[128]; + +#ifdef TRAIN_RES + FILE *of; + char buffer[80]; + int m; + for(i=0;imode,pass); + of=fopen(buffer,"a"); + for(m=0;mend;m++) + fprintf(of,"%.2f, ",in[i][m]); + fprintf(of,"\n"); + fclose(of); } +#endif + + memset(resbits,0,sizeof(resbits)); + memset(resvals,0,sizeof(resvals)); + /* we code the partition words for each channel, then the residual words for a partition per channel until we've written all the residual words for that partition word. Then write the next - parition channel words... */ - - for(i=info->begin,l=0;iend;){ - /* first we encode a partition codeword for each channel */ - for(j=0;jphrasebook,val,&vb->opb); - } - /* now we encode interleaved residual values for the partitions */ - for(k=0;kopb,in[j]+i,samples_per_partition, - info->secondstages[partword[j][l]], - look->partbooks[partword[j][l]]); - resvals[partword[j][l]]+=samples_per_partition; + partition channel words... */ + + for(s=(pass==0?0:info->passlimit[pass-1]);spasslimit[pass];s++){ + for(i=0;iphrasebook->entries) + ret=vorbis_book_encode(look->phrasebook,val,&vb->opb); + /*else + fprintf(stderr,"!");*/ + + look->phrasebits+=ret; + + } } + /* now we encode interleaved residual values for the partitions */ + for(k=0;kbegin; + + for(j=0;jsecondstages[partword[j][i]]&(1<partbooks[partword[j][i]][s]; + if(statebook){ + int ret=encode(&vb->opb,in[j]+offset,samples_per_partition, + statebook,look); + look->postbits+=ret; + resbits[partword[j][i]]+=ret; + } + } + } + } + } } - for(i=0;iend-info->begin),phrasebits,resbitsT); - for(i=0;imode); + for(k=0;kpcmend/2; +static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, + float **in,int ch, + long (*decodepart)(codebook *, float *, + oggpack_buffer *,int)){ + + long i,j,k,l,s; vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; vorbis_info_residue0 *info=look->info; @@ -318,56 +588,281 @@ int inverse(vorbis_block *vb,vorbis_look_residue *vl,double **in,int ch){ int samples_per_partition=info->grouping; int partitions_per_word=look->phrasebook->dim; int n=info->end-info->begin; - + int partvals=n/samples_per_partition; int partwords=(partvals+partitions_per_word-1)/partitions_per_word; - int **partword=alloca(ch*sizeof(long *)); - double *work=alloca(sizeof(double)*samples_per_partition); - partvals=partwords*partitions_per_word; + int ***partword=alloca(ch*sizeof(int **)); - /* make sure we're zeroed up to the start */ for(j=0;jbegin); - - for(i=info->begin,l=0;iend;){ - /* fetch the partition word for each channel */ - for(j=0;jphrasebook,&vb->opb); - if(temp==-1)goto eopbreak; - partword[j]=look->decodemap[temp]; - if(partword[j]==NULL)goto errout; - } - - /* now we decode interleaved residual values for the partitions */ - for(k=0;kopb,work,in[j]+i,samples_per_partition, - info->secondstages[part], - look->partbooks[part])==-1)goto eopbreak; + partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(int *)); + + for(s=0;sstages;s++){ + + /* each loop decodes on partition codeword containing + partitions_pre_word partitions */ + for(i=0,l=0;iphrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[j][l]=look->decodemap[temp]; + if(partword[j][l]==NULL)goto errout; + } } + + /* now we decode residual values for the partitions */ + for(k=0;kbegin+i*samples_per_partition; + if(info->secondstages[partword[j][l][k]]&(1<partbooks[partword[j][l][k]][s]; + if(stagebook){ + if(decodepart(stagebook,in[j]+offset,&vb->opb, + samples_per_partition)==-1)goto eopbreak; + } + } + } + } } - + + errout: eopbreak: - if(ipcmend/2; + for(i=0;ipcmend/2; + for(i=0;ipcmend/2,used=0; + + /* don't duplicate the code; use a working vector hack for now and + reshape ourselves into a single channel res1 */ + /* ugly; reallocs for each coupling pass :-( */ + float *work=_vorbis_block_alloc(vb,ch*n*sizeof(float)); + for(i=0;iinfo; + /* move all this setup out later */ + int samples_per_partition=info->grouping; + int partitions_per_word=look->phrasebook->dim; + int n=info->end-info->begin; + + int partvals=n/samples_per_partition; + int partwords=(partvals+partitions_per_word-1)/partitions_per_word; + int **partword=_vorbis_block_alloc(vb,partwords*sizeof(int *)); + + for(i=0;istages;s++){ + for(i=0,l=0;iphrasebook,&vb->opb); + if(temp==-1)goto eopbreak; + partword[l]=look->decodemap[temp]; + if(partword[l]==NULL)goto errout; + } + + /* now we decode residual values for the partitions */ + for(k=0;ksecondstages[partword[l][k]]&(1<partbooks[partword[l][k]][s]; + + if(stagebook){ + if(vorbis_book_decodevv_add(stagebook,in, + i*samples_per_partition+info->begin,ch, + &vb->opb,samples_per_partition)==-1) + goto eopbreak; + } + } + } + } + errout: - for(j=0;j