1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
9 * by the XIPHOPHORUS Company http://www.xiph.org/ *
11 ********************************************************************
13 function: floor backend 1 implementation
14 last mod: $Id: floor1.c,v 1.21 2002/06/28 22:19:35 xiphmont Exp $
16 ********************************************************************/
22 #include "vorbis/codec.h"
23 #include "codec_internal.h"
31 #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
34 int sorted_index[VIF_POSIT+2];
35 int forward_index[VIF_POSIT+2];
36 int reverse_index[VIF_POSIT+2];
38 int hineighbor[VIF_POSIT];
39 int loneighbor[VIF_POSIT];
44 vorbis_info_floor1 *vi;
51 typedef struct lsfit_acc{
66 /***********************************************/
68 static void floor1_free_info(vorbis_info_floor *i){
69 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
71 memset(info,0,sizeof(*info));
76 static void floor1_free_look(vorbis_look_floor *i){
77 vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
79 /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n",
80 (float)look->phrasebits/look->frames,
81 (float)look->postbits/look->frames,
82 (float)(look->postbits+look->phrasebits)/look->frames);*/
84 memset(look,0,sizeof(*look));
89 static int ilog(unsigned int v){
98 static int ilog2(unsigned int v){
107 static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
108 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
112 int maxposit=info->postlist[1];
115 /* save out partitions */
116 oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */
117 for(j=0;j<info->partitions;j++){
118 oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */
119 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
122 /* save out partition classes */
123 for(j=0;j<maxclass+1;j++){
124 oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
125 oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
126 if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
127 for(k=0;k<(1<<info->class_subs[j]);k++)
128 oggpack_write(opb,info->class_subbook[j][k]+1,8);
131 /* save out the post list */
132 oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */
133 oggpack_write(opb,ilog2(maxposit),4);
134 rangebits=ilog2(maxposit);
136 for(j=0,k=0;j<info->partitions;j++){
137 count+=info->class_dim[info->partitionclass[j]];
139 oggpack_write(opb,info->postlist[k+2],rangebits);
144 static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
145 codec_setup_info *ci=vi->codec_setup;
146 int j,k,count=0,maxclass=-1,rangebits;
148 vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info));
149 /* read partitions */
150 info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
151 for(j=0;j<info->partitions;j++){
152 info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
153 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
156 /* read partition classes */
157 for(j=0;j<maxclass+1;j++){
158 info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
159 info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
160 if(info->class_subs[j]<0)
162 if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
163 if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
165 for(k=0;k<(1<<info->class_subs[j]);k++){
166 info->class_subbook[j][k]=oggpack_read(opb,8)-1;
167 if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
172 /* read the post list */
173 info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
174 rangebits=oggpack_read(opb,4);
176 for(j=0,k=0;j<info->partitions;j++){
177 count+=info->class_dim[info->partitionclass[j]];
179 int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
180 if(t<0 || t>=(1<<rangebits))
185 info->postlist[1]=1<<rangebits;
190 floor1_free_info(info);
194 static int icomp(const void *a,const void *b){
195 return(**(int **)a-**(int **)b);
198 static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,
199 vorbis_info_floor *in){
201 int *sortpointer[VIF_POSIT+2];
202 vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
203 vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(*look));
207 look->n=info->postlist[1];
209 /* we drop each position value in-between already decoded values,
210 and use linear interpolation to predict each new value past the
211 edges. The positions are read in the order of the position
212 list... we precompute the bounding positions in the lookup. Of
213 course, the neighbors can change (if a position is declined), but
214 this is an initial mapping */
216 for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
220 /* also store a sorted position index */
221 for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
222 qsort(sortpointer,n,sizeof(*sortpointer),icomp);
224 /* points from sort order back to range number */
225 for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
226 /* points from range order to sorted position */
227 for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
228 /* we actually need the post values too */
229 for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
231 /* quantize values to multiplier spec */
233 case 1: /* 1024 -> 256 */
236 case 2: /* 1024 -> 128 */
239 case 3: /* 1024 -> 86 */
242 case 4: /* 1024 -> 64 */
247 /* discover our neighbors for decode where we don't use fit flags
248 (that would push the neighbors outward) */
254 int currentx=info->postlist[i+2];
256 int x=info->postlist[j];
257 if(x>lx && x<currentx){
261 if(x<hx && x>currentx){
266 look->loneighbor[i]=lo;
267 look->hineighbor[i]=hi;
273 static int render_point(int x0,int x1,int y0,int y1,int x){
274 y0&=0x7fff; /* mask off flag */
284 if(dy<0)return(y0-off);
289 static int vorbis_dBquant(const float *x){
290 int i= *x*7.3142857f+1023.5f;
291 if(i>1023)return(1023);
296 static float FLOOR1_fromdB_LOOKUP[256]={
297 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
298 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
299 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
300 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
301 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
302 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
303 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
304 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
305 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
306 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
307 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
308 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
309 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
310 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
311 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
312 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
313 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
314 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
315 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
316 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
317 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
318 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
319 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
320 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
321 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
322 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
323 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
324 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
325 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
326 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
327 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
328 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
329 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
330 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
331 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
332 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
333 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
334 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
335 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
336 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
337 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
338 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
339 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
340 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
341 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
342 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
343 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
344 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
345 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
346 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
347 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
348 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
349 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
350 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
351 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
352 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
353 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
354 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
355 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
356 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
357 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
358 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
359 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
360 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
363 static void render_line(int x0,int x1,int y0,int y1,float *d){
368 int sy=(dy<0?base-1:base+1);
375 d[x]*=FLOOR1_fromdB_LOOKUP[y];
384 d[x]*=FLOOR1_fromdB_LOOKUP[y];
388 static void render_line0(int x0,int x1,int y0,int y1,int *d){
393 int sy=(dy<0?base-1:base+1);
413 /* the floor has already been filtered to only include relevant sections */
414 static int accumulate_fit(const float *flr,const float *mdct,
415 int x0, int x1,lsfit_acc *a,
416 int n,vorbis_info_floor1 *info){
418 int quantized=vorbis_dBquant(flr+x0);
420 long xa=0,ya=0,x2a=0,y2a=0,xya=0,na=0, xb=0,yb=0,x2b=0,y2b=0,xyb=0,nb=0;
422 memset(a,0,sizeof(*a));
429 int quantized=vorbis_dBquant(flr+i);
431 if(mdct[i]+info->twofitatten>=flr[i]){
435 y2a += quantized*quantized;
442 y2b += quantized*quantized;
456 /* weight toward the actually used frequencies if we meet the threshhold */
458 int weight=info->twofitweight/na;
462 a->x2a=x2a*weight+x2b;
463 a->y2a=y2a*weight+y2b;
464 a->xya=xya*weight+xyb;
471 int quantized=vorbis_dBquant(flr+i);
477 static void fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
478 long x=0,y=0,x2=0,y2=0,xy=0,n=0,an=0,i;
480 long x1=a[fits-1].x1;
513 /* need 64 bit multiplies, which C doesn't give portably as int */
518 double denom=1./(an*fx2-fx*fx);
519 double a=(fy*fx2-fxy*fx)*denom;
520 double b=(an*fxy-fx*fy)*denom;
524 /* limit to our range! */
525 if(*y0>1023)*y0=1023;
526 if(*y1>1023)*y1=1023;
533 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
537 for(i=0;i<fits && y==0;i++)
543 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
545 vorbis_info_floor1 *info){
550 int sy=(dy<0?base-1:base+1);
554 int val=vorbis_dBquant(mask+x);
563 if(mdct[x]+info->twofitatten>=mask[x]){
564 if(y+info->maxover<val)return(1);
565 if(y-info->maxunder>val)return(1);
577 val=vorbis_dBquant(mask+x);
578 mse+=((y-val)*(y-val));
580 if(mdct[x]+info->twofitatten>=mask[x]){
582 if(y+info->maxover<val)return(1);
583 if(y-info->maxunder>val)return(1);
588 if(info->maxover*info->maxover/n>info->maxerr)return(0);
589 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
590 if(mse/n>info->maxerr)return(1);
594 static int post_Y(int *A,int *B,int pos){
600 return (A[pos]+B[pos])>>1;
605 int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
606 const float *logmdct, /* in */
607 const float *logmask){
609 vorbis_info_floor1 *info=look->vi;
611 long posts=look->posts;
613 lsfit_acc fits[VIF_POSIT+1];
614 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
615 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
617 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
618 int hineighbor[VIF_POSIT+2];
620 int memo[VIF_POSIT+2];
622 for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
623 for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
624 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
625 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
626 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
628 /* quantize the relevant floor points and collect them into line fit
629 structures (one per minimal division) at the same time */
631 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
633 for(i=0;i<posts-1;i++)
634 nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
635 look->sorted_index[i+1],fits+i,
640 /* start by fitting the implicit base case.... */
643 fit_line(fits,posts-1,&y0,&y1);
650 /* Non degenerate case */
651 /* start progressive splitting. This is a greedy, non-optimal
652 algorithm, but simple and close enough to the best
654 for(i=2;i<posts;i++){
655 int sortpos=look->reverse_index[i];
656 int ln=loneighbor[sortpos];
657 int hn=hineighbor[sortpos];
659 /* eliminate repeat searches of a particular range with a memo */
661 /* haven't performed this error search yet */
662 int lsortpos=look->reverse_index[ln];
663 int hsortpos=look->reverse_index[hn];
667 /* A note: we want to bound/minimize *local*, not global, error */
668 int lx=info->postlist[ln];
669 int hx=info->postlist[hn];
670 int ly=post_Y(fit_valueA,fit_valueB,ln);
671 int hy=post_Y(fit_valueA,fit_valueB,hn);
673 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
674 /* outside error bounds/begin search area. Split it. */
679 fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
680 fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
682 /* store new edge values */
684 if(ln==0)fit_valueA[ln]=ly0;
688 if(hn==1)fit_valueB[hn]=hy1;
690 if(ly1>=0 || hy0>=0){
691 /* store new neighbor values */
692 for(j=sortpos-1;j>=0;j--)
693 if(hineighbor[j]==hn)
697 for(j=sortpos+1;j<posts;j++)
698 if(loneighbor[j]==ln)
713 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
715 output[0]=post_Y(fit_valueA,fit_valueB,0);
716 output[1]=post_Y(fit_valueA,fit_valueB,1);
718 /* fill in posts marked as not using a fit; we will zero
719 back out to 'unused' when encoding them so long as curve
720 interpolation doesn't force them into use */
721 for(i=2;i<posts;i++){
722 int ln=look->loneighbor[i-2];
723 int hn=look->hineighbor[i-2];
724 int x0=info->postlist[ln];
725 int x1=info->postlist[hn];
729 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
730 int vx=post_Y(fit_valueA,fit_valueB,i);
732 if(vx>=0 && predicted!=vx){
735 output[i]= predicted|0x8000;
744 int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
749 long posts=look->posts;
753 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
755 for(i=0;i<posts;i++){
756 output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
757 if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
765 int floor1_encode(vorbis_block *vb,vorbis_look_floor1 *look,
766 int *post,int *ilogmask){
769 vorbis_info_floor1 *info=look->vi;
771 long posts=look->posts;
772 codec_setup_info *ci=vb->vd->vi->codec_setup;
773 int out[VIF_POSIT+2];
774 static_codebook **sbooks=ci->book_param;
775 codebook *books=ci->fullbooks;
778 /* quantize values to multiplier spec */
780 for(i=0;i<posts;i++){
781 int val=post[i]&0x7fff;
783 case 1: /* 1024 -> 256 */
786 case 2: /* 1024 -> 128 */
789 case 3: /* 1024 -> 86 */
792 case 4: /* 1024 -> 64 */
796 post[i]=val | (post[i]&0x8000);
802 /* find prediction values for each post and subtract them */
803 for(i=2;i<posts;i++){
804 int ln=look->loneighbor[i-2];
805 int hn=look->hineighbor[i-2];
806 int x0=info->postlist[ln];
807 int x1=info->postlist[hn];
811 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
813 if((post[i]&0x8000) || (predicted==post[i])){
814 post[i]=predicted|0x8000; /* in case there was roundoff jitter
818 int headroom=(look->quant_q-predicted<predicted?
819 look->quant_q-predicted:predicted);
821 int val=post[i]-predicted;
823 /* at this point the 'deviation' value is in the range +/- max
824 range, but the real, unique range can always be mapped to
825 only [0-maxrange). So we want to wrap the deviation into
826 this limited range, but do it in the way that least screws
827 an essentially gaussian probability distribution. */
846 /* we have everything we need. pack it out */
847 /* mark nontrivial floor */
848 oggpack_write(&vb->opb,1,1);
850 /* beginning/end post */
852 look->postbits+=ilog(look->quant_q-1)*2;
853 oggpack_write(&vb->opb,out[0],ilog(look->quant_q-1));
854 oggpack_write(&vb->opb,out[1],ilog(look->quant_q-1));
857 /* partition by partition */
858 for(i=0,j=2;i<info->partitions;i++){
859 int class=info->partitionclass[i];
860 int cdim=info->class_dim[class];
861 int csubbits=info->class_subs[class];
862 int csub=1<<csubbits;
863 int bookas[8]={0,0,0,0,0,0,0,0};
868 /* generate the partition's first stage cascade value */
872 int booknum=info->class_subbook[class][k];
876 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
887 cval|= bookas[k]<<cshift;
892 vorbis_book_encode(books+info->class_book[class],cval,&vb->opb);
898 sprintf(buffer,"line_%dx%ld_class%d.vqd",
899 vb->pcmend/2,posts-2,class);
900 of=fopen(buffer,"a");
901 fprintf(of,"%d\n",cval);
907 /* write post values */
909 int book=info->class_subbook[class][bookas[k]];
911 /* hack to allow training with 'bad' books */
912 if(out[j+k]<(books+book)->entries)
913 look->postbits+=vorbis_book_encode(books+book,
916 fprintf(stderr,"+!");*/
922 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
923 vb->pcmend/2,posts-2,class,bookas[k]);
924 of=fopen(buffer,"a");
925 fprintf(of,"%d\n",out[j+k]);
935 /* generate quantized floor equivalent to what we'd unpack in decode */
936 /* render the lines */
939 int ly=post[0]*info->mult;
940 for(j=1;j<look->posts;j++){
941 int current=look->forward_index[j];
942 int hy=post[current]&0x7fff;
943 if(hy==post[current]){
946 hx=info->postlist[current];
948 render_line0(lx,hx,ly,hy,ilogmask);
954 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
959 oggpack_write(&vb->opb,0,1);
960 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
966 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
967 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
968 vorbis_info_floor1 *info=look->vi;
969 codec_setup_info *ci=vb->vd->vi->codec_setup;
972 codebook *books=ci->fullbooks;
974 /* unpack wrapped/predicted values from stream */
975 if(oggpack_read(&vb->opb,1)==1){
976 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
978 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
979 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
981 /* partition by partition */
982 for(i=0,j=2;i<info->partitions;i++){
983 int class=info->partitionclass[i];
984 int cdim=info->class_dim[class];
985 int csubbits=info->class_subs[class];
986 int csub=1<<csubbits;
989 /* decode the partition's first stage cascade value */
991 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
993 if(cval==-1)goto eop;
997 int book=info->class_subbook[class][cval&(csub-1)];
1000 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1009 /* unwrap positive values and reconsitute via linear interpolation */
1010 for(i=2;i<look->posts;i++){
1011 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1012 info->postlist[look->hineighbor[i-2]],
1013 fit_value[look->loneighbor[i-2]],
1014 fit_value[look->hineighbor[i-2]],
1016 int hiroom=look->quant_q-predicted;
1017 int loroom=predicted;
1018 int room=(hiroom<loroom?hiroom:loroom)<<1;
1019 int val=fit_value[i];
1026 val = -1-(val-hiroom);
1036 fit_value[i]=val+predicted;
1037 fit_value[look->loneighbor[i-2]]&=0x7fff;
1038 fit_value[look->hineighbor[i-2]]&=0x7fff;
1041 fit_value[i]=predicted|0x8000;
1052 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1054 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1055 vorbis_info_floor1 *info=look->vi;
1057 codec_setup_info *ci=vb->vd->vi->codec_setup;
1058 int n=ci->blocksizes[vb->W]/2;
1062 /* render the lines */
1063 int *fit_value=(int *)memo;
1066 int ly=fit_value[0]*info->mult;
1067 for(j=1;j<look->posts;j++){
1068 int current=look->forward_index[j];
1069 int hy=fit_value[current]&0x7fff;
1070 if(hy==fit_value[current]){
1073 hx=info->postlist[current];
1075 render_line(lx,hx,ly,hy,out);
1081 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1084 memset(out,0,sizeof(*out)*n);
1089 vorbis_func_floor floor1_exportbundle={
1090 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
1091 &floor1_free_look,&floor1_inverse1,&floor1_inverse2