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.26 2003/02/15 07:10:07 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(vorbis_block *vb,vorbis_look_floor1 *look,
761 int *post,int *ilogmask){
764 vorbis_info_floor1 *info=look->vi;
766 long posts=look->posts;
767 codec_setup_info *ci=vb->vd->vi->codec_setup;
768 int out[VIF_POSIT+2];
769 static_codebook **sbooks=ci->book_param;
770 codebook *books=ci->fullbooks;
773 /* quantize values to multiplier spec */
775 for(i=0;i<posts;i++){
776 int val=post[i]&0x7fff;
778 case 1: /* 1024 -> 256 */
781 case 2: /* 1024 -> 128 */
784 case 3: /* 1024 -> 86 */
787 case 4: /* 1024 -> 64 */
791 post[i]=val | (post[i]&0x8000);
797 /* find prediction values for each post and subtract them */
798 for(i=2;i<posts;i++){
799 int ln=look->loneighbor[i-2];
800 int hn=look->hineighbor[i-2];
801 int x0=info->postlist[ln];
802 int x1=info->postlist[hn];
806 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
808 if((post[i]&0x8000) || (predicted==post[i])){
809 post[i]=predicted|0x8000; /* in case there was roundoff jitter
813 int headroom=(look->quant_q-predicted<predicted?
814 look->quant_q-predicted:predicted);
816 int val=post[i]-predicted;
818 /* at this point the 'deviation' value is in the range +/- max
819 range, but the real, unique range can always be mapped to
820 only [0-maxrange). So we want to wrap the deviation into
821 this limited range, but do it in the way that least screws
822 an essentially gaussian probability distribution. */
841 /* we have everything we need. pack it out */
842 /* mark nontrivial floor */
843 oggpack_write(&vb->opb,1,1);
845 /* beginning/end post */
847 look->postbits+=ilog(look->quant_q-1)*2;
848 oggpack_write(&vb->opb,out[0],ilog(look->quant_q-1));
849 oggpack_write(&vb->opb,out[1],ilog(look->quant_q-1));
852 /* partition by partition */
853 for(i=0,j=2;i<info->partitions;i++){
854 int class=info->partitionclass[i];
855 int cdim=info->class_dim[class];
856 int csubbits=info->class_subs[class];
857 int csub=1<<csubbits;
858 int bookas[8]={0,0,0,0,0,0,0,0};
863 /* generate the partition's first stage cascade value */
867 int booknum=info->class_subbook[class][k];
871 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
882 cval|= bookas[k]<<cshift;
887 vorbis_book_encode(books+info->class_book[class],cval,&vb->opb);
893 sprintf(buffer,"line_%dx%ld_class%d.vqd",
894 vb->pcmend/2,posts-2,class);
895 of=fopen(buffer,"a");
896 fprintf(of,"%d\n",cval);
902 /* write post values */
904 int book=info->class_subbook[class][bookas[k]];
906 /* hack to allow training with 'bad' books */
907 if(out[j+k]<(books+book)->entries)
908 look->postbits+=vorbis_book_encode(books+book,
911 fprintf(stderr,"+!");*/
917 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
918 vb->pcmend/2,posts-2,class,bookas[k]);
919 of=fopen(buffer,"a");
920 fprintf(of,"%d\n",out[j+k]);
930 /* generate quantized floor equivalent to what we'd unpack in decode */
931 /* render the lines */
934 int ly=post[0]*info->mult;
935 for(j=1;j<look->posts;j++){
936 int current=look->forward_index[j];
937 int hy=post[current]&0x7fff;
938 if(hy==post[current]){
941 hx=info->postlist[current];
943 render_line0(lx,hx,ly,hy,ilogmask);
949 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
954 oggpack_write(&vb->opb,0,1);
955 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
961 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
962 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
963 vorbis_info_floor1 *info=look->vi;
964 codec_setup_info *ci=vb->vd->vi->codec_setup;
967 codebook *books=ci->fullbooks;
969 /* unpack wrapped/predicted values from stream */
970 if(oggpack_read(&vb->opb,1)==1){
971 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
973 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
974 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
976 /* partition by partition */
977 for(i=0,j=2;i<info->partitions;i++){
978 int class=info->partitionclass[i];
979 int cdim=info->class_dim[class];
980 int csubbits=info->class_subs[class];
981 int csub=1<<csubbits;
984 /* decode the partition's first stage cascade value */
986 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
988 if(cval==-1)goto eop;
992 int book=info->class_subbook[class][cval&(csub-1)];
995 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1004 /* unwrap positive values and reconsitute via linear interpolation */
1005 for(i=2;i<look->posts;i++){
1006 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1007 info->postlist[look->hineighbor[i-2]],
1008 fit_value[look->loneighbor[i-2]],
1009 fit_value[look->hineighbor[i-2]],
1011 int hiroom=look->quant_q-predicted;
1012 int loroom=predicted;
1013 int room=(hiroom<loroom?hiroom:loroom)<<1;
1014 int val=fit_value[i];
1021 val = -1-(val-hiroom);
1031 fit_value[i]=val+predicted;
1032 fit_value[look->loneighbor[i-2]]&=0x7fff;
1033 fit_value[look->hineighbor[i-2]]&=0x7fff;
1036 fit_value[i]=predicted|0x8000;
1047 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1049 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1050 vorbis_info_floor1 *info=look->vi;
1052 codec_setup_info *ci=vb->vd->vi->codec_setup;
1053 int n=ci->blocksizes[vb->W]/2;
1057 /* render the lines */
1058 int *fit_value=(int *)memo;
1061 int ly=fit_value[0]*info->mult;
1062 for(j=1;j<look->posts;j++){
1063 int current=look->forward_index[j];
1064 int hy=fit_value[current]&0x7fff;
1065 if(hy==fit_value[current]){
1068 hx=info->postlist[current];
1070 render_line(lx,hx,ly,hy,out);
1076 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1079 memset(out,0,sizeof(*out)*n);
1084 vorbis_func_floor floor1_exportbundle={
1085 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
1086 &floor1_free_look,&floor1_inverse1,&floor1_inverse2