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.27 2003/12/30 11:02:22 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{
63 /***********************************************/
65 static void floor1_free_info(vorbis_info_floor *i){
66 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
68 memset(info,0,sizeof(*info));
73 static void floor1_free_look(vorbis_look_floor *i){
74 vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
76 /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n",
77 (float)look->phrasebits/look->frames,
78 (float)look->postbits/look->frames,
79 (float)(look->postbits+look->phrasebits)/look->frames);*/
81 memset(look,0,sizeof(*look));
86 static int ilog(unsigned int v){
95 static int ilog2(unsigned int v){
105 static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
106 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
110 int maxposit=info->postlist[1];
113 /* save out partitions */
114 oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */
115 for(j=0;j<info->partitions;j++){
116 oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */
117 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
120 /* save out partition classes */
121 for(j=0;j<maxclass+1;j++){
122 oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
123 oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
124 if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
125 for(k=0;k<(1<<info->class_subs[j]);k++)
126 oggpack_write(opb,info->class_subbook[j][k]+1,8);
129 /* save out the post list */
130 oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */
131 oggpack_write(opb,ilog2(maxposit),4);
132 rangebits=ilog2(maxposit);
134 for(j=0,k=0;j<info->partitions;j++){
135 count+=info->class_dim[info->partitionclass[j]];
137 oggpack_write(opb,info->postlist[k+2],rangebits);
142 static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
143 codec_setup_info *ci=vi->codec_setup;
144 int j,k,count=0,maxclass=-1,rangebits;
146 vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info));
147 /* read partitions */
148 info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
149 for(j=0;j<info->partitions;j++){
150 info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
151 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
154 /* read partition classes */
155 for(j=0;j<maxclass+1;j++){
156 info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
157 info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
158 if(info->class_subs[j]<0)
160 if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
161 if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
163 for(k=0;k<(1<<info->class_subs[j]);k++){
164 info->class_subbook[j][k]=oggpack_read(opb,8)-1;
165 if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
170 /* read the post list */
171 info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
172 rangebits=oggpack_read(opb,4);
174 for(j=0,k=0;j<info->partitions;j++){
175 count+=info->class_dim[info->partitionclass[j]];
177 int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
178 if(t<0 || t>=(1<<rangebits))
183 info->postlist[1]=1<<rangebits;
188 floor1_free_info(info);
192 static int icomp(const void *a,const void *b){
193 return(**(int **)a-**(int **)b);
196 static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,
197 vorbis_info_floor *in){
199 int *sortpointer[VIF_POSIT+2];
200 vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
201 vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(*look));
205 look->n=info->postlist[1];
207 /* we drop each position value in-between already decoded values,
208 and use linear interpolation to predict each new value past the
209 edges. The positions are read in the order of the position
210 list... we precompute the bounding positions in the lookup. Of
211 course, the neighbors can change (if a position is declined), but
212 this is an initial mapping */
214 for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
218 /* also store a sorted position index */
219 for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
220 qsort(sortpointer,n,sizeof(*sortpointer),icomp);
222 /* points from sort order back to range number */
223 for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
224 /* points from range order to sorted position */
225 for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
226 /* we actually need the post values too */
227 for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
229 /* quantize values to multiplier spec */
231 case 1: /* 1024 -> 256 */
234 case 2: /* 1024 -> 128 */
237 case 3: /* 1024 -> 86 */
240 case 4: /* 1024 -> 64 */
245 /* discover our neighbors for decode where we don't use fit flags
246 (that would push the neighbors outward) */
252 int currentx=info->postlist[i+2];
254 int x=info->postlist[j];
255 if(x>lx && x<currentx){
259 if(x<hx && x>currentx){
264 look->loneighbor[i]=lo;
265 look->hineighbor[i]=hi;
271 static int render_point(int x0,int x1,int y0,int y1,int x){
272 y0&=0x7fff; /* mask off flag */
282 if(dy<0)return(y0-off);
287 static int vorbis_dBquant(const float *x){
288 int i= *x*7.3142857f+1023.5f;
289 if(i>1023)return(1023);
294 static float FLOOR1_fromdB_LOOKUP[256]={
295 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
296 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
297 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
298 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
299 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
300 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
301 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
302 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
303 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
304 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
305 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
306 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
307 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
308 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
309 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
310 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
311 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
312 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
313 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
314 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
315 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
316 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
317 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
318 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
319 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
320 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
321 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
322 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
323 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
324 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
325 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
326 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
327 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
328 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
329 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
330 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
331 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
332 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
333 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
334 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
335 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
336 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
337 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
338 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
339 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
340 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
341 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
342 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
343 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
344 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
345 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
346 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
347 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
348 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
349 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
350 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
351 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
352 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
353 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
354 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
355 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
356 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
357 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
358 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
361 static void render_line(int x0,int x1,int y0,int y1,float *d){
366 int sy=(dy<0?base-1:base+1);
373 d[x]*=FLOOR1_fromdB_LOOKUP[y];
382 d[x]*=FLOOR1_fromdB_LOOKUP[y];
386 static void render_line0(int x0,int x1,int y0,int y1,int *d){
391 int sy=(dy<0?base-1:base+1);
411 /* the floor has already been filtered to only include relevant sections */
412 static int accumulate_fit(const float *flr,const float *mdct,
413 int x0, int x1,lsfit_acc *a,
414 int n,vorbis_info_floor1 *info){
416 int quantized=vorbis_dBquant(flr+x0);
418 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;
420 memset(a,0,sizeof(*a));
426 int quantized=vorbis_dBquant(flr+i);
428 if(mdct[i]+info->twofitatten>=flr[i]){
432 y2a += quantized*quantized;
439 y2b += quantized*quantized;
453 /* weight toward the actually used frequencies if we meet the threshhold */
455 int weight=nb*info->twofitweight/(na+1);
459 a->x2a=x2a*weight+x2b;
460 a->y2a=y2a*weight+y2b;
461 a->xya=xya*weight+xyb;
468 static void fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
469 long x=0,y=0,x2=0,y2=0,xy=0,an=0,i;
471 long x1=a[fits-1].x1;
501 /* need 64 bit multiplies, which C doesn't give portably as int */
506 double denom=1./(an*fx2-fx*fx);
507 double a=(fy*fx2-fxy*fx)*denom;
508 double b=(an*fxy-fx*fy)*denom;
512 /* limit to our range! */
513 if(*y0>1023)*y0=1023;
514 if(*y1>1023)*y1=1023;
524 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
528 for(i=0;i<fits && y==0;i++)
534 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
536 vorbis_info_floor1 *info){
541 int sy=(dy<0?base-1:base+1);
545 int val=vorbis_dBquant(mask+x);
554 if(mdct[x]+info->twofitatten>=mask[x]){
555 if(y+info->maxover<val)return(1);
556 if(y-info->maxunder>val)return(1);
568 val=vorbis_dBquant(mask+x);
569 mse+=((y-val)*(y-val));
571 if(mdct[x]+info->twofitatten>=mask[x]){
573 if(y+info->maxover<val)return(1);
574 if(y-info->maxunder>val)return(1);
579 if(info->maxover*info->maxover/n>info->maxerr)return(0);
580 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
581 if(mse/n>info->maxerr)return(1);
585 static int post_Y(int *A,int *B,int pos){
591 return (A[pos]+B[pos])>>1;
596 int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
597 const float *logmdct, /* in */
598 const float *logmask){
600 vorbis_info_floor1 *info=look->vi;
602 long posts=look->posts;
604 lsfit_acc fits[VIF_POSIT+1];
605 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
606 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
608 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
609 int hineighbor[VIF_POSIT+2];
611 int memo[VIF_POSIT+2];
613 for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
614 for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
615 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
616 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
617 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
619 /* quantize the relevant floor points and collect them into line fit
620 structures (one per minimal division) at the same time */
622 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
624 for(i=0;i<posts-1;i++)
625 nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
626 look->sorted_index[i+1],fits+i,
631 /* start by fitting the implicit base case.... */
634 fit_line(fits,posts-1,&y0,&y1);
641 /* Non degenerate case */
642 /* start progressive splitting. This is a greedy, non-optimal
643 algorithm, but simple and close enough to the best
645 for(i=2;i<posts;i++){
646 int sortpos=look->reverse_index[i];
647 int ln=loneighbor[sortpos];
648 int hn=hineighbor[sortpos];
650 /* eliminate repeat searches of a particular range with a memo */
652 /* haven't performed this error search yet */
653 int lsortpos=look->reverse_index[ln];
654 int hsortpos=look->reverse_index[hn];
658 /* A note: we want to bound/minimize *local*, not global, error */
659 int lx=info->postlist[ln];
660 int hx=info->postlist[hn];
661 int ly=post_Y(fit_valueA,fit_valueB,ln);
662 int hy=post_Y(fit_valueA,fit_valueB,hn);
664 if(ly==-1 || hy==-1){
668 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
669 /* outside error bounds/begin search area. Split it. */
674 fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
675 fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
677 /* store new edge values */
679 if(ln==0)fit_valueA[ln]=ly0;
683 if(hn==1)fit_valueB[hn]=hy1;
685 if(ly1>=0 || hy0>=0){
686 /* store new neighbor values */
687 for(j=sortpos-1;j>=0;j--)
688 if(hineighbor[j]==hn)
692 for(j=sortpos+1;j<posts;j++)
693 if(loneighbor[j]==ln)
708 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
710 output[0]=post_Y(fit_valueA,fit_valueB,0);
711 output[1]=post_Y(fit_valueA,fit_valueB,1);
713 /* fill in posts marked as not using a fit; we will zero
714 back out to 'unused' when encoding them so long as curve
715 interpolation doesn't force them into use */
716 for(i=2;i<posts;i++){
717 int ln=look->loneighbor[i-2];
718 int hn=look->hineighbor[i-2];
719 int x0=info->postlist[ln];
720 int x1=info->postlist[hn];
724 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
725 int vx=post_Y(fit_valueA,fit_valueB,i);
727 if(vx>=0 && predicted!=vx){
730 output[i]= predicted|0x8000;
739 int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
744 long posts=look->posts;
748 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
750 for(i=0;i<posts;i++){
751 output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
752 if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
760 int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
761 vorbis_look_floor1 *look,
762 int *post,int *ilogmask){
765 vorbis_info_floor1 *info=look->vi;
767 long posts=look->posts;
768 codec_setup_info *ci=vb->vd->vi->codec_setup;
769 int out[VIF_POSIT+2];
770 static_codebook **sbooks=ci->book_param;
771 codebook *books=ci->fullbooks;
774 /* quantize values to multiplier spec */
776 for(i=0;i<posts;i++){
777 int val=post[i]&0x7fff;
779 case 1: /* 1024 -> 256 */
782 case 2: /* 1024 -> 128 */
785 case 3: /* 1024 -> 86 */
788 case 4: /* 1024 -> 64 */
792 post[i]=val | (post[i]&0x8000);
798 /* find prediction values for each post and subtract them */
799 for(i=2;i<posts;i++){
800 int ln=look->loneighbor[i-2];
801 int hn=look->hineighbor[i-2];
802 int x0=info->postlist[ln];
803 int x1=info->postlist[hn];
807 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
809 if((post[i]&0x8000) || (predicted==post[i])){
810 post[i]=predicted|0x8000; /* in case there was roundoff jitter
814 int headroom=(look->quant_q-predicted<predicted?
815 look->quant_q-predicted:predicted);
817 int val=post[i]-predicted;
819 /* at this point the 'deviation' value is in the range +/- max
820 range, but the real, unique range can always be mapped to
821 only [0-maxrange). So we want to wrap the deviation into
822 this limited range, but do it in the way that least screws
823 an essentially gaussian probability distribution. */
842 /* we have everything we need. pack it out */
843 /* mark nontrivial floor */
844 oggpack_write(opb,1,1);
846 /* beginning/end post */
848 look->postbits+=ilog(look->quant_q-1)*2;
849 oggpack_write(opb,out[0],ilog(look->quant_q-1));
850 oggpack_write(opb,out[1],ilog(look->quant_q-1));
853 /* partition by partition */
854 for(i=0,j=2;i<info->partitions;i++){
855 int class=info->partitionclass[i];
856 int cdim=info->class_dim[class];
857 int csubbits=info->class_subs[class];
858 int csub=1<<csubbits;
859 int bookas[8]={0,0,0,0,0,0,0,0};
864 /* generate the partition's first stage cascade value */
868 int booknum=info->class_subbook[class][k];
872 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
883 cval|= bookas[k]<<cshift;
888 vorbis_book_encode(books+info->class_book[class],cval,opb);
894 sprintf(buffer,"line_%dx%ld_class%d.vqd",
895 vb->pcmend/2,posts-2,class);
896 of=fopen(buffer,"a");
897 fprintf(of,"%d\n",cval);
903 /* write post values */
905 int book=info->class_subbook[class][bookas[k]];
907 /* hack to allow training with 'bad' books */
908 if(out[j+k]<(books+book)->entries)
909 look->postbits+=vorbis_book_encode(books+book,
912 fprintf(stderr,"+!");*/
918 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
919 vb->pcmend/2,posts-2,class,bookas[k]);
920 of=fopen(buffer,"a");
921 fprintf(of,"%d\n",out[j+k]);
931 /* generate quantized floor equivalent to what we'd unpack in decode */
932 /* render the lines */
935 int ly=post[0]*info->mult;
936 for(j=1;j<look->posts;j++){
937 int current=look->forward_index[j];
938 int hy=post[current]&0x7fff;
939 if(hy==post[current]){
942 hx=info->postlist[current];
944 render_line0(lx,hx,ly,hy,ilogmask);
950 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
955 oggpack_write(opb,0,1);
956 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
962 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
963 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
964 vorbis_info_floor1 *info=look->vi;
965 codec_setup_info *ci=vb->vd->vi->codec_setup;
968 codebook *books=ci->fullbooks;
970 /* unpack wrapped/predicted values from stream */
971 if(oggpack_read(&vb->opb,1)==1){
972 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
974 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
975 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
977 /* partition by partition */
978 for(i=0,j=2;i<info->partitions;i++){
979 int class=info->partitionclass[i];
980 int cdim=info->class_dim[class];
981 int csubbits=info->class_subs[class];
982 int csub=1<<csubbits;
985 /* decode the partition's first stage cascade value */
987 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
989 if(cval==-1)goto eop;
993 int book=info->class_subbook[class][cval&(csub-1)];
996 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1005 /* unwrap positive values and reconsitute via linear interpolation */
1006 for(i=2;i<look->posts;i++){
1007 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1008 info->postlist[look->hineighbor[i-2]],
1009 fit_value[look->loneighbor[i-2]],
1010 fit_value[look->hineighbor[i-2]],
1012 int hiroom=look->quant_q-predicted;
1013 int loroom=predicted;
1014 int room=(hiroom<loroom?hiroom:loroom)<<1;
1015 int val=fit_value[i];
1022 val = -1-(val-hiroom);
1032 fit_value[i]=val+predicted;
1033 fit_value[look->loneighbor[i-2]]&=0x7fff;
1034 fit_value[look->hineighbor[i-2]]&=0x7fff;
1037 fit_value[i]=predicted|0x8000;
1048 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1050 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1051 vorbis_info_floor1 *info=look->vi;
1053 codec_setup_info *ci=vb->vd->vi->codec_setup;
1054 int n=ci->blocksizes[vb->W]/2;
1058 /* render the lines */
1059 int *fit_value=(int *)memo;
1062 int ly=fit_value[0]*info->mult;
1063 for(j=1;j<look->posts;j++){
1064 int current=look->forward_index[j];
1065 int hy=fit_value[current]&0x7fff;
1066 if(hy==fit_value[current]){
1069 hx=info->postlist[current];
1071 render_line(lx,hx,ly,hy,out);
1077 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1080 memset(out,0,sizeof(*out)*n);
1085 vorbis_func_floor floor1_exportbundle={
1086 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
1087 &floor1_free_look,&floor1_inverse1,&floor1_inverse2