michael@0: /******************************************************************** michael@0: * * michael@0: * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * michael@0: * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * michael@0: * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * michael@0: * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * michael@0: * * michael@0: * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * michael@0: * by the Xiph.Org Foundation http://www.xiph.org/ * michael@0: * * michael@0: ******************************************************************** michael@0: michael@0: function: residue backend 0, 1 and 2 implementation michael@0: last mod: $Id: res0.c 19031 2013-12-03 19:20:50Z tterribe $ michael@0: michael@0: ********************************************************************/ michael@0: michael@0: /* Slow, slow, slow, simpleminded and did I mention it was slow? The michael@0: encode/decode loops are coded for clarity and performance is not michael@0: yet even a nagging little idea lurking in the shadows. Oh and BTW, michael@0: it's slow. */ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include "vorbis/codec.h" michael@0: #include "codec_internal.h" michael@0: #include "registry.h" michael@0: #include "codebook.h" michael@0: #include "misc.h" michael@0: #include "os.h" michael@0: michael@0: //#define TRAIN_RES 1 michael@0: //#define TRAIN_RESAUX 1 michael@0: michael@0: #if defined(TRAIN_RES) || defined (TRAIN_RESAUX) michael@0: #include michael@0: #endif michael@0: michael@0: typedef struct { michael@0: vorbis_info_residue0 *info; michael@0: michael@0: int parts; michael@0: int stages; michael@0: codebook *fullbooks; michael@0: codebook *phrasebook; michael@0: codebook ***partbooks; michael@0: michael@0: int partvals; michael@0: int **decodemap; michael@0: michael@0: long postbits; michael@0: long phrasebits; michael@0: long frames; michael@0: michael@0: #if defined(TRAIN_RES) || defined(TRAIN_RESAUX) michael@0: int train_seq; michael@0: long *training_data[8][64]; michael@0: float training_max[8][64]; michael@0: float training_min[8][64]; michael@0: float tmin; michael@0: float tmax; michael@0: int submap; michael@0: #endif michael@0: michael@0: } vorbis_look_residue0; michael@0: michael@0: void res0_free_info(vorbis_info_residue *i){ michael@0: vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; michael@0: if(info){ michael@0: memset(info,0,sizeof(*info)); michael@0: _ogg_free(info); michael@0: } michael@0: } michael@0: michael@0: void res0_free_look(vorbis_look_residue *i){ michael@0: int j; michael@0: if(i){ michael@0: michael@0: vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; michael@0: michael@0: #ifdef TRAIN_RES michael@0: { michael@0: int j,k,l; michael@0: for(j=0;jparts;j++){ michael@0: /*fprintf(stderr,"partition %d: ",j);*/ michael@0: for(k=0;k<8;k++) michael@0: if(look->training_data[k][j]){ michael@0: char buffer[80]; michael@0: FILE *of; michael@0: codebook *statebook=look->partbooks[j][k]; michael@0: michael@0: /* long and short into the same bucket by current convention */ michael@0: sprintf(buffer,"res_sub%d_part%d_pass%d.vqd",look->submap,j,k); michael@0: of=fopen(buffer,"a"); michael@0: michael@0: for(l=0;lentries;l++) michael@0: fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]); michael@0: michael@0: fclose(of); michael@0: michael@0: /*fprintf(stderr,"%d(%.2f|%.2f) ",k, michael@0: look->training_min[k][j],look->training_max[k][j]);*/ michael@0: michael@0: _ogg_free(look->training_data[k][j]); michael@0: look->training_data[k][j]=NULL; michael@0: } michael@0: /*fprintf(stderr,"\n");*/ michael@0: } michael@0: } michael@0: fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax); michael@0: michael@0: /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n", michael@0: (float)look->phrasebits/look->frames, michael@0: (float)look->postbits/look->frames, michael@0: (float)(look->postbits+look->phrasebits)/look->frames);*/ michael@0: #endif michael@0: michael@0: michael@0: /*vorbis_info_residue0 *info=look->info; michael@0: michael@0: fprintf(stderr, michael@0: "%ld frames encoded in %ld phrasebits and %ld residue bits " michael@0: "(%g/frame) \n",look->frames,look->phrasebits, michael@0: look->resbitsflat, michael@0: (look->phrasebits+look->resbitsflat)/(float)look->frames); michael@0: michael@0: for(j=0;jparts;j++){ michael@0: long acc=0; michael@0: fprintf(stderr,"\t[%d] == ",j); michael@0: for(k=0;kstages;k++) michael@0: if((info->secondstages[j]>>k)&1){ michael@0: fprintf(stderr,"%ld,",look->resbits[j][k]); michael@0: acc+=look->resbits[j][k]; michael@0: } michael@0: michael@0: fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j], michael@0: acc?(float)acc/(look->resvals[j]*info->grouping):0); michael@0: } michael@0: fprintf(stderr,"\n");*/ michael@0: michael@0: for(j=0;jparts;j++) michael@0: if(look->partbooks[j])_ogg_free(look->partbooks[j]); michael@0: _ogg_free(look->partbooks); michael@0: for(j=0;jpartvals;j++) michael@0: _ogg_free(look->decodemap[j]); michael@0: _ogg_free(look->decodemap); michael@0: michael@0: memset(look,0,sizeof(*look)); michael@0: _ogg_free(look); michael@0: } michael@0: } michael@0: michael@0: static int ilog(unsigned int v){ michael@0: int ret=0; michael@0: while(v){ michael@0: ret++; michael@0: v>>=1; michael@0: } michael@0: return(ret); michael@0: } michael@0: michael@0: static int icount(unsigned int v){ michael@0: int ret=0; michael@0: while(v){ michael@0: ret+=v&1; michael@0: v>>=1; michael@0: } michael@0: return(ret); michael@0: } michael@0: michael@0: michael@0: void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){ michael@0: vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; michael@0: int j,acc=0; michael@0: oggpack_write(opb,info->begin,24); michael@0: oggpack_write(opb,info->end,24); michael@0: michael@0: oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and michael@0: code with a partitioned book */ michael@0: oggpack_write(opb,info->partitions-1,6); /* possible partition choices */ michael@0: oggpack_write(opb,info->groupbook,8); /* group huffman book */ michael@0: michael@0: /* secondstages is a bitmask; as encoding progresses pass by pass, a michael@0: bitmask of one indicates this partition class has bits to write michael@0: this pass */ michael@0: for(j=0;jpartitions;j++){ michael@0: if(ilog(info->secondstages[j])>3){ michael@0: /* yes, this is a minor hack due to not thinking ahead */ michael@0: oggpack_write(opb,info->secondstages[j],3); michael@0: oggpack_write(opb,1,1); michael@0: oggpack_write(opb,info->secondstages[j]>>3,5); michael@0: }else michael@0: oggpack_write(opb,info->secondstages[j],4); /* trailing zero */ michael@0: acc+=icount(info->secondstages[j]); michael@0: } michael@0: for(j=0;jbooklist[j],8); michael@0: michael@0: } michael@0: michael@0: /* vorbis_info is for range checking */ michael@0: vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ michael@0: int j,acc=0; michael@0: vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info)); michael@0: codec_setup_info *ci=vi->codec_setup; michael@0: michael@0: info->begin=oggpack_read(opb,24); michael@0: info->end=oggpack_read(opb,24); michael@0: info->grouping=oggpack_read(opb,24)+1; michael@0: info->partitions=oggpack_read(opb,6)+1; michael@0: info->groupbook=oggpack_read(opb,8); michael@0: michael@0: /* check for premature EOP */ michael@0: if(info->groupbook<0)goto errout; michael@0: michael@0: for(j=0;jpartitions;j++){ michael@0: int cascade=oggpack_read(opb,3); michael@0: int cflag=oggpack_read(opb,1); michael@0: if(cflag<0) goto errout; michael@0: if(cflag){ michael@0: int c=oggpack_read(opb,5); michael@0: if(c<0) goto errout; michael@0: cascade|=(c<<3); michael@0: } michael@0: info->secondstages[j]=cascade; michael@0: michael@0: acc+=icount(cascade); michael@0: } michael@0: for(j=0;jbooklist[j]=book; michael@0: } michael@0: michael@0: if(info->groupbook>=ci->books)goto errout; michael@0: for(j=0;jbooklist[j]>=ci->books)goto errout; michael@0: if(ci->book_param[info->booklist[j]]->maptype==0)goto errout; michael@0: } michael@0: michael@0: /* verify the phrasebook is not specifying an impossible or michael@0: inconsistent partitioning scheme. */ michael@0: /* modify the phrasebook ranging check from r16327; an early beta michael@0: encoder had a bug where it used an oversized phrasebook by michael@0: accident. These files should continue to be playable, but don't michael@0: allow an exploit */ michael@0: { michael@0: int entries = ci->book_param[info->groupbook]->entries; michael@0: int dim = ci->book_param[info->groupbook]->dim; michael@0: int partvals = 1; michael@0: if (dim<1) goto errout; michael@0: while(dim>0){ michael@0: partvals *= info->partitions; michael@0: if(partvals > entries) goto errout; michael@0: dim--; michael@0: } michael@0: info->partvals = partvals; michael@0: } michael@0: michael@0: return(info); michael@0: errout: michael@0: res0_free_info(info); michael@0: return(NULL); michael@0: } michael@0: michael@0: vorbis_look_residue *res0_look(vorbis_dsp_state *vd, michael@0: vorbis_info_residue *vr){ michael@0: vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; michael@0: vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look)); michael@0: codec_setup_info *ci=vd->vi->codec_setup; michael@0: michael@0: int j,k,acc=0; michael@0: int dim; michael@0: int maxstage=0; michael@0: look->info=info; michael@0: michael@0: look->parts=info->partitions; michael@0: look->fullbooks=ci->fullbooks; michael@0: look->phrasebook=ci->fullbooks+info->groupbook; michael@0: dim=look->phrasebook->dim; michael@0: michael@0: look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks)); michael@0: michael@0: for(j=0;jparts;j++){ michael@0: int stages=ilog(info->secondstages[j]); michael@0: if(stages){ michael@0: if(stages>maxstage)maxstage=stages; michael@0: look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j])); michael@0: for(k=0;ksecondstages[j]&(1<partbooks[j][k]=ci->fullbooks+info->booklist[acc++]; michael@0: #ifdef TRAIN_RES michael@0: look->training_data[k][j]=_ogg_calloc(look->partbooks[j][k]->entries, michael@0: sizeof(***look->training_data)); michael@0: #endif michael@0: } michael@0: } michael@0: } michael@0: michael@0: look->partvals=1; michael@0: for(j=0;jpartvals*=look->parts; michael@0: michael@0: look->stages=maxstage; michael@0: look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap)); michael@0: for(j=0;jpartvals;j++){ michael@0: long val=j; michael@0: long mult=look->partvals/look->parts; michael@0: look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j])); michael@0: for(k=0;kparts; michael@0: look->decodemap[j][k]=deco; michael@0: } michael@0: } michael@0: #if defined(TRAIN_RES) || defined (TRAIN_RESAUX) michael@0: { michael@0: static int train_seq=0; michael@0: look->train_seq=train_seq++; michael@0: } michael@0: #endif michael@0: return(look); michael@0: } michael@0: michael@0: /* break an abstraction and copy some code for performance purposes */ michael@0: static int local_book_besterror(codebook *book,int *a){ michael@0: int dim=book->dim; michael@0: int i,j,o; michael@0: int minval=book->minval; michael@0: int del=book->delta; michael@0: int qv=book->quantvals; michael@0: int ze=(qv>>1); michael@0: int index=0; michael@0: /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */ michael@0: int p[8]={0,0,0,0,0,0,0,0}; michael@0: michael@0: if(del!=1){ michael@0: for(i=0,o=dim;i>1))/del; michael@0: int m = (v=qv?qv-1:m)); michael@0: p[o]=v*del+minval; michael@0: } michael@0: }else{ michael@0: for(i=0,o=dim;i=qv?qv-1:m)); michael@0: p[o]=v*del+minval; michael@0: } michael@0: } michael@0: michael@0: if(book->c->lengthlist[index]<=0){ michael@0: const static_codebook *c=book->c; michael@0: int best=-1; michael@0: /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */ michael@0: int e[8]={0,0,0,0,0,0,0,0}; michael@0: int maxval = book->minval + book->delta*(book->quantvals-1); michael@0: for(i=0;ientries;i++){ michael@0: if(c->lengthlist[i]>0){ michael@0: int this=0; michael@0: for(j=0;j=maxval) michael@0: e[j++]=0; michael@0: if(e[j]>=0) michael@0: e[j]+=book->delta; michael@0: e[j]= -e[j]; michael@0: } michael@0: } michael@0: michael@0: if(index>-1){ michael@0: for(i=0;idim; michael@0: int step=n/dim; michael@0: michael@0: for(i=0;i=0) michael@0: acc[entry]++; michael@0: #endif michael@0: michael@0: bits+=vorbis_book_encode(book,entry,opb); michael@0: michael@0: } michael@0: michael@0: return(bits); michael@0: } michael@0: michael@0: static long **_01class(vorbis_block *vb,vorbis_look_residue *vl, michael@0: int **in,int ch){ michael@0: long i,j,k; michael@0: vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; michael@0: vorbis_info_residue0 *info=look->info; michael@0: michael@0: /* move all this setup out later */ michael@0: int samples_per_partition=info->grouping; michael@0: int possible_partitions=info->partitions; michael@0: int n=info->end-info->begin; michael@0: michael@0: int partvals=n/samples_per_partition; michael@0: long **partword=_vorbis_block_alloc(vb,ch*sizeof(*partword)); michael@0: float scale=100./samples_per_partition; michael@0: michael@0: /* we find the partition type for each partition of each michael@0: channel. We'll go back and do the interleaved encoding in a michael@0: bit. For now, clarity */ michael@0: michael@0: for(i=0;ibegin; michael@0: for(j=0;jmax)max=abs(in[j][offset+k]); michael@0: ent+=abs(in[j][offset+k]); michael@0: } michael@0: ent*=scale; michael@0: michael@0: for(k=0;kclassmetric1[k] && michael@0: (info->classmetric2[k]<0 || entclassmetric2[k])) michael@0: break; michael@0: michael@0: partword[j][i]=k; michael@0: } michael@0: } michael@0: michael@0: #ifdef TRAIN_RESAUX michael@0: { michael@0: FILE *of; michael@0: char buffer[80]; michael@0: michael@0: for(i=0;itrain_seq); michael@0: of=fopen(buffer,"a"); michael@0: for(j=0;jframes++; michael@0: michael@0: return(partword); michael@0: } michael@0: michael@0: /* designed for stereo or other modes where the partition size is an michael@0: integer multiple of the number of channels encoded in the current michael@0: submap */ michael@0: static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,int **in, michael@0: int ch){ michael@0: long i,j,k,l; michael@0: vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; michael@0: vorbis_info_residue0 *info=look->info; michael@0: michael@0: /* move all this setup out later */ michael@0: int samples_per_partition=info->grouping; michael@0: int possible_partitions=info->partitions; michael@0: int n=info->end-info->begin; michael@0: michael@0: int partvals=n/samples_per_partition; michael@0: long **partword=_vorbis_block_alloc(vb,sizeof(*partword)); michael@0: michael@0: #if defined(TRAIN_RES) || defined (TRAIN_RESAUX) michael@0: FILE *of; michael@0: char buffer[80]; michael@0: #endif michael@0: michael@0: partword[0]=_vorbis_block_alloc(vb,partvals*sizeof(*partword[0])); michael@0: memset(partword[0],0,partvals*sizeof(*partword[0])); michael@0: michael@0: for(i=0,l=info->begin/ch;imagmax)magmax=abs(in[0][l]); michael@0: for(k=1;kangmax)angmax=abs(in[k][l]); michael@0: l++; michael@0: } michael@0: michael@0: for(j=0;jclassmetric1[j] && michael@0: angmax<=info->classmetric2[j]) michael@0: break; michael@0: michael@0: partword[0][i]=j; michael@0: michael@0: } michael@0: michael@0: #ifdef TRAIN_RESAUX michael@0: sprintf(buffer,"resaux_%d.vqd",look->train_seq); michael@0: of=fopen(buffer,"a"); michael@0: for(i=0;iframes++; michael@0: michael@0: return(partword); michael@0: } michael@0: michael@0: static int _01forward(oggpack_buffer *opb, michael@0: vorbis_look_residue *vl, michael@0: int **in,int ch, michael@0: long **partword, michael@0: #ifdef TRAIN_RES michael@0: int (*encode)(oggpack_buffer *,int *,int, michael@0: codebook *,long *), michael@0: int submap michael@0: #else michael@0: int (*encode)(oggpack_buffer *,int *,int, michael@0: codebook *) michael@0: #endif michael@0: ){ michael@0: long i,j,k,s; michael@0: vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; michael@0: vorbis_info_residue0 *info=look->info; michael@0: michael@0: #ifdef TRAIN_RES michael@0: look->submap=submap; michael@0: #endif michael@0: michael@0: /* move all this setup out later */ michael@0: int samples_per_partition=info->grouping; michael@0: int possible_partitions=info->partitions; michael@0: int partitions_per_word=look->phrasebook->dim; michael@0: int n=info->end-info->begin; michael@0: michael@0: int partvals=n/samples_per_partition; michael@0: long resbits[128]; michael@0: long resvals[128]; michael@0: michael@0: #ifdef TRAIN_RES michael@0: for(i=0;ibegin;jend;j++){ michael@0: if(in[i][j]>look->tmax)look->tmax=in[i][j]; michael@0: if(in[i][j]tmin)look->tmin=in[i][j]; michael@0: } michael@0: #endif michael@0: michael@0: memset(resbits,0,sizeof(resbits)); michael@0: memset(resvals,0,sizeof(resvals)); michael@0: michael@0: /* we code the partition words for each channel, then the residual michael@0: words for a partition per channel until we've written all the michael@0: residual words for that partition word. Then write the next michael@0: partition channel words... */ michael@0: michael@0: for(s=0;sstages;s++){ michael@0: michael@0: for(i=0;iphrasebook->entries) michael@0: look->phrasebits+=vorbis_book_encode(look->phrasebook,val,opb); michael@0: #if 0 /*def TRAIN_RES*/ michael@0: else michael@0: fprintf(stderr,"!"); michael@0: #endif michael@0: michael@0: } michael@0: } michael@0: michael@0: /* now we encode interleaved residual values for the partitions */ michael@0: for(k=0;kbegin; michael@0: michael@0: for(j=0;jsecondstages[partword[j][i]]&(1<partbooks[partword[j][i]][s]; michael@0: if(statebook){ michael@0: int ret; michael@0: #ifdef TRAIN_RES michael@0: long *accumulator=NULL; michael@0: accumulator=look->training_data[s][partword[j][i]]; michael@0: { michael@0: int l; michael@0: int *samples=in[j]+offset; michael@0: for(l=0;ltraining_min[s][partword[j][i]]) michael@0: look->training_min[s][partword[j][i]]=samples[l]; michael@0: if(samples[l]>look->training_max[s][partword[j][i]]) michael@0: look->training_max[s][partword[j][i]]=samples[l]; michael@0: } michael@0: } michael@0: ret=encode(opb,in[j]+offset,samples_per_partition, michael@0: statebook,accumulator); michael@0: #else michael@0: ret=encode(opb,in[j]+offset,samples_per_partition, michael@0: statebook); michael@0: #endif michael@0: michael@0: look->postbits+=ret; michael@0: resbits[partword[j][i]]+=ret; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: return(0); michael@0: } michael@0: michael@0: /* a truncated packet here just means 'stop working'; it's not an error */ michael@0: static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, michael@0: float **in,int ch, michael@0: long (*decodepart)(codebook *, float *, michael@0: oggpack_buffer *,int)){ michael@0: michael@0: long i,j,k,l,s; michael@0: vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; michael@0: vorbis_info_residue0 *info=look->info; michael@0: michael@0: /* move all this setup out later */ michael@0: int samples_per_partition=info->grouping; michael@0: int partitions_per_word=look->phrasebook->dim; michael@0: int max=vb->pcmend>>1; michael@0: int end=(info->endend:max); michael@0: int n=end-info->begin; michael@0: michael@0: if(n>0){ michael@0: int partvals=n/samples_per_partition; michael@0: int partwords=(partvals+partitions_per_word-1)/partitions_per_word; michael@0: int ***partword=alloca(ch*sizeof(*partword)); michael@0: michael@0: for(j=0;jstages;s++){ michael@0: michael@0: /* each loop decodes on partition codeword containing michael@0: partitions_per_word partitions */ michael@0: for(i=0,l=0;iphrasebook,&vb->opb); michael@0: michael@0: if(temp==-1 || temp>=info->partvals)goto eopbreak; michael@0: partword[j][l]=look->decodemap[temp]; michael@0: if(partword[j][l]==NULL)goto errout; michael@0: } michael@0: } michael@0: michael@0: /* now we decode residual values for the partitions */ michael@0: for(k=0;kbegin+i*samples_per_partition; michael@0: if(info->secondstages[partword[j][l][k]]&(1<partbooks[partword[j][l][k]][s]; michael@0: if(stagebook){ michael@0: if(decodepart(stagebook,in[j]+offset,&vb->opb, michael@0: samples_per_partition)==-1)goto eopbreak; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: errout: michael@0: eopbreak: michael@0: return(0); michael@0: } michael@0: michael@0: int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl, michael@0: float **in,int *nonzero,int ch){ michael@0: int i,used=0; michael@0: for(i=0;ipcmend/2,used=0; michael@0: michael@0: /* don't duplicate the code; use a working vector hack for now and michael@0: reshape ourselves into a single channel res1 */ michael@0: /* ugly; reallocs for each coupling pass :-( */ michael@0: int *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work)); michael@0: for(i=0;iinfo; michael@0: michael@0: /* move all this setup out later */ michael@0: int samples_per_partition=info->grouping; michael@0: int partitions_per_word=look->phrasebook->dim; michael@0: int max=(vb->pcmend*ch)>>1; michael@0: int end=(info->endend:max); michael@0: int n=end-info->begin; michael@0: michael@0: if(n>0){ michael@0: int partvals=n/samples_per_partition; michael@0: int partwords=(partvals+partitions_per_word-1)/partitions_per_word; michael@0: int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword)); michael@0: michael@0: for(i=0;istages;s++){ michael@0: for(i=0,l=0;iphrasebook,&vb->opb); michael@0: if(temp==-1 || temp>=info->partvals)goto eopbreak; michael@0: partword[l]=look->decodemap[temp]; michael@0: if(partword[l]==NULL)goto errout; michael@0: } michael@0: michael@0: /* now we decode residual values for the partitions */ michael@0: for(k=0;ksecondstages[partword[l][k]]&(1<partbooks[partword[l][k]][s]; michael@0: michael@0: if(stagebook){ michael@0: if(vorbis_book_decodevv_add(stagebook,in, michael@0: i*samples_per_partition+info->begin,ch, michael@0: &vb->opb,samples_per_partition)==-1) michael@0: goto eopbreak; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: errout: michael@0: eopbreak: michael@0: return(0); michael@0: } michael@0: michael@0: michael@0: const vorbis_func_residue residue0_exportbundle={ michael@0: NULL, michael@0: &res0_unpack, michael@0: &res0_look, michael@0: &res0_free_info, michael@0: &res0_free_look, michael@0: NULL, michael@0: NULL, michael@0: &res0_inverse michael@0: }; michael@0: michael@0: const vorbis_func_residue residue1_exportbundle={ michael@0: &res0_pack, michael@0: &res0_unpack, michael@0: &res0_look, michael@0: &res0_free_info, michael@0: &res0_free_look, michael@0: &res1_class, michael@0: &res1_forward, michael@0: &res1_inverse michael@0: }; michael@0: michael@0: const vorbis_func_residue residue2_exportbundle={ michael@0: &res0_pack, michael@0: &res0_unpack, michael@0: &res0_look, michael@0: &res0_free_info, michael@0: &res0_free_look, michael@0: &res2_class, michael@0: &res2_forward, michael@0: &res2_inverse michael@0: };