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.23 2002/07/11 06:40:48 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{
64 /***********************************************/
66 static void floor1_free_info(vorbis_info_floor *i){
67 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
69 memset(info,0,sizeof(*info));
74 static void floor1_free_look(vorbis_look_floor *i){
75 vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
77 /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n",
78 (float)look->phrasebits/look->frames,
79 (float)look->postbits/look->frames,
80 (float)(look->postbits+look->phrasebits)/look->frames);*/
82 memset(look,0,sizeof(*look));
87 static int ilog(unsigned int v){
96 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;
469 static void fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
470 long x=0,y=0,x2=0,y2=0,xy=0,n=0,an=0,i;
472 long x1=a[fits-1].x1;
505 /* need 64 bit multiplies, which C doesn't give portably as int */
510 double denom=1./(an*fx2-fx*fx);
511 double a=(fy*fx2-fxy*fx)*denom;
512 double b=(an*fxy-fx*fy)*denom;
516 /* limit to our range! */
517 if(*y0>1023)*y0=1023;
518 if(*y1>1023)*y1=1023;
525 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
529 for(i=0;i<fits && y==0;i++)
535 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
537 vorbis_info_floor1 *info){
542 int sy=(dy<0?base-1:base+1);
546 int val=vorbis_dBquant(mask+x);
555 if(mdct[x]+info->twofitatten>=mask[x]){
556 if(y+info->maxover<val)return(1);
557 if(y-info->maxunder>val)return(1);
569 val=vorbis_dBquant(mask+x);
570 mse+=((y-val)*(y-val));
572 if(mdct[x]+info->twofitatten>=mask[x]){
574 if(y+info->maxover<val)return(1);
575 if(y-info->maxunder>val)return(1);
580 if(info->maxover*info->maxover/n>info->maxerr)return(0);
581 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
582 if(mse/n>info->maxerr)return(1);
586 static int post_Y(int *A,int *B,int pos){
592 return (A[pos]+B[pos])>>1;
597 int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
598 const float *logmdct, /* in */
599 const float *logmask){
601 vorbis_info_floor1 *info=look->vi;
603 long posts=look->posts;
605 lsfit_acc fits[VIF_POSIT+1];
606 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
607 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
609 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
610 int hineighbor[VIF_POSIT+2];
612 int memo[VIF_POSIT+2];
614 for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
615 for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
616 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
617 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
618 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
620 /* quantize the relevant floor points and collect them into line fit
621 structures (one per minimal division) at the same time */
623 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
625 for(i=0;i<posts-1;i++)
626 nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
627 look->sorted_index[i+1],fits+i,
632 /* start by fitting the implicit base case.... */
635 fit_line(fits,posts-1,&y0,&y1);
642 /* Non degenerate case */
643 /* start progressive splitting. This is a greedy, non-optimal
644 algorithm, but simple and close enough to the best
646 for(i=2;i<posts;i++){
647 int sortpos=look->reverse_index[i];
648 int ln=loneighbor[sortpos];
649 int hn=hineighbor[sortpos];
651 /* eliminate repeat searches of a particular range with a memo */
653 /* haven't performed this error search yet */
654 int lsortpos=look->reverse_index[ln];
655 int hsortpos=look->reverse_index[hn];
659 /* A note: we want to bound/minimize *local*, not global, error */
660 int lx=info->postlist[ln];
661 int hx=info->postlist[hn];
662 int ly=post_Y(fit_valueA,fit_valueB,ln);
663 int hy=post_Y(fit_valueA,fit_valueB,hn);
665 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
666 /* outside error bounds/begin search area. Split it. */
671 fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
672 fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
674 /* store new edge values */
676 if(ln==0)fit_valueA[ln]=ly0;
680 if(hn==1)fit_valueB[hn]=hy1;
682 if(ly1>=0 || hy0>=0){
683 /* store new neighbor values */
684 for(j=sortpos-1;j>=0;j--)
685 if(hineighbor[j]==hn)
689 for(j=sortpos+1;j<posts;j++)
690 if(loneighbor[j]==ln)
705 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
707 output[0]=post_Y(fit_valueA,fit_valueB,0);
708 output[1]=post_Y(fit_valueA,fit_valueB,1);
710 /* fill in posts marked as not using a fit; we will zero
711 back out to 'unused' when encoding them so long as curve
712 interpolation doesn't force them into use */
713 for(i=2;i<posts;i++){
714 int ln=look->loneighbor[i-2];
715 int hn=look->hineighbor[i-2];
716 int x0=info->postlist[ln];
717 int x1=info->postlist[hn];
721 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
722 int vx=post_Y(fit_valueA,fit_valueB,i);
724 if(vx>=0 && predicted!=vx){
727 output[i]= predicted|0x8000;
736 int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
741 long posts=look->posts;
745 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
747 for(i=0;i<posts;i++){
748 output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
749 if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
757 int floor1_encode(vorbis_block *vb,vorbis_look_floor1 *look,
758 int *post,int *ilogmask){
761 vorbis_info_floor1 *info=look->vi;
763 long posts=look->posts;
764 codec_setup_info *ci=vb->vd->vi->codec_setup;
765 int out[VIF_POSIT+2];
766 static_codebook **sbooks=ci->book_param;
767 codebook *books=ci->fullbooks;
770 /* quantize values to multiplier spec */
772 for(i=0;i<posts;i++){
773 int val=post[i]&0x7fff;
775 case 1: /* 1024 -> 256 */
778 case 2: /* 1024 -> 128 */
781 case 3: /* 1024 -> 86 */
784 case 4: /* 1024 -> 64 */
788 post[i]=val | (post[i]&0x8000);
794 /* find prediction values for each post and subtract them */
795 for(i=2;i<posts;i++){
796 int ln=look->loneighbor[i-2];
797 int hn=look->hineighbor[i-2];
798 int x0=info->postlist[ln];
799 int x1=info->postlist[hn];
803 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
805 if((post[i]&0x8000) || (predicted==post[i])){
806 post[i]=predicted|0x8000; /* in case there was roundoff jitter
810 int headroom=(look->quant_q-predicted<predicted?
811 look->quant_q-predicted:predicted);
813 int val=post[i]-predicted;
815 /* at this point the 'deviation' value is in the range +/- max
816 range, but the real, unique range can always be mapped to
817 only [0-maxrange). So we want to wrap the deviation into
818 this limited range, but do it in the way that least screws
819 an essentially gaussian probability distribution. */
838 /* we have everything we need. pack it out */
839 /* mark nontrivial floor */
840 oggpack_write(&vb->opb,1,1);
842 /* beginning/end post */
844 look->postbits+=ilog(look->quant_q-1)*2;
845 oggpack_write(&vb->opb,out[0],ilog(look->quant_q-1));
846 oggpack_write(&vb->opb,out[1],ilog(look->quant_q-1));
849 /* partition by partition */
850 for(i=0,j=2;i<info->partitions;i++){
851 int class=info->partitionclass[i];
852 int cdim=info->class_dim[class];
853 int csubbits=info->class_subs[class];
854 int csub=1<<csubbits;
855 int bookas[8]={0,0,0,0,0,0,0,0};
860 /* generate the partition's first stage cascade value */
864 int booknum=info->class_subbook[class][k];
868 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
879 cval|= bookas[k]<<cshift;
884 vorbis_book_encode(books+info->class_book[class],cval,&vb->opb);
890 sprintf(buffer,"line_%dx%ld_class%d.vqd",
891 vb->pcmend/2,posts-2,class);
892 of=fopen(buffer,"a");
893 fprintf(of,"%d\n",cval);
899 /* write post values */
901 int book=info->class_subbook[class][bookas[k]];
903 /* hack to allow training with 'bad' books */
904 if(out[j+k]<(books+book)->entries)
905 look->postbits+=vorbis_book_encode(books+book,
908 fprintf(stderr,"+!");*/
914 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
915 vb->pcmend/2,posts-2,class,bookas[k]);
916 of=fopen(buffer,"a");
917 fprintf(of,"%d\n",out[j+k]);
927 /* generate quantized floor equivalent to what we'd unpack in decode */
928 /* render the lines */
931 int ly=post[0]*info->mult;
932 for(j=1;j<look->posts;j++){
933 int current=look->forward_index[j];
934 int hy=post[current]&0x7fff;
935 if(hy==post[current]){
938 hx=info->postlist[current];
940 render_line0(lx,hx,ly,hy,ilogmask);
946 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
951 oggpack_write(&vb->opb,0,1);
952 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
958 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
959 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
960 vorbis_info_floor1 *info=look->vi;
961 codec_setup_info *ci=vb->vd->vi->codec_setup;
964 codebook *books=ci->fullbooks;
966 /* unpack wrapped/predicted values from stream */
967 if(oggpack_read(&vb->opb,1)==1){
968 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
970 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
971 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
973 /* partition by partition */
974 for(i=0,j=2;i<info->partitions;i++){
975 int class=info->partitionclass[i];
976 int cdim=info->class_dim[class];
977 int csubbits=info->class_subs[class];
978 int csub=1<<csubbits;
981 /* decode the partition's first stage cascade value */
983 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
985 if(cval==-1)goto eop;
989 int book=info->class_subbook[class][cval&(csub-1)];
992 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1001 /* unwrap positive values and reconsitute via linear interpolation */
1002 for(i=2;i<look->posts;i++){
1003 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1004 info->postlist[look->hineighbor[i-2]],
1005 fit_value[look->loneighbor[i-2]],
1006 fit_value[look->hineighbor[i-2]],
1008 int hiroom=look->quant_q-predicted;
1009 int loroom=predicted;
1010 int room=(hiroom<loroom?hiroom:loroom)<<1;
1011 int val=fit_value[i];
1018 val = -1-(val-hiroom);
1028 fit_value[i]=val+predicted;
1029 fit_value[look->loneighbor[i-2]]&=0x7fff;
1030 fit_value[look->hineighbor[i-2]]&=0x7fff;
1033 fit_value[i]=predicted|0x8000;
1044 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1046 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1047 vorbis_info_floor1 *info=look->vi;
1049 codec_setup_info *ci=vb->vd->vi->codec_setup;
1050 int n=ci->blocksizes[vb->W]/2;
1054 /* render the lines */
1055 int *fit_value=(int *)memo;
1058 int ly=fit_value[0]*info->mult;
1059 for(j=1;j<look->posts;j++){
1060 int current=look->forward_index[j];
1061 int hy=fit_value[current]&0x7fff;
1062 if(hy==fit_value[current]){
1065 hx=info->postlist[current];
1067 render_line(lx,hx,ly,hy,out);
1073 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1076 memset(out,0,sizeof(*out)*n);
1081 vorbis_func_floor floor1_exportbundle={
1082 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
1083 &floor1_free_look,&floor1_inverse1,&floor1_inverse2