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-2007 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: floor backend 1 implementation
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 n, int x0,int x1,int y0,int y1,float *d){
366 int sy=(dy<0?base-1:base+1);
376 d[x]*=FLOOR1_fromdB_LOOKUP[y];
386 d[x]*=FLOOR1_fromdB_LOOKUP[y];
390 static void render_line0(int x0,int x1,int y0,int y1,int *d){
395 int sy=(dy<0?base-1:base+1);
415 /* the floor has already been filtered to only include relevant sections */
416 static int accumulate_fit(const float *flr,const float *mdct,
417 int x0, int x1,lsfit_acc *a,
418 int n,vorbis_info_floor1 *info){
420 int quantized=vorbis_dBquant(flr+x0);
422 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;
424 memset(a,0,sizeof(*a));
430 int quantized=vorbis_dBquant(flr+i);
432 if(mdct[i]+info->twofitatten>=flr[i]){
436 y2a += quantized*quantized;
443 y2b += quantized*quantized;
457 /* weight toward the actually used frequencies if we meet the threshhold */
459 int weight=nb*info->twofitweight/(na+1);
463 a->x2a=x2a*weight+x2b;
464 a->y2a=y2a*weight+y2b;
465 a->xya=xya*weight+xyb;
472 static void fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
473 long x=0,y=0,x2=0,y2=0,xy=0,an=0,i;
475 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;
528 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
532 for(i=0;i<fits && y==0;i++)
538 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
540 vorbis_info_floor1 *info){
545 int sy=(dy<0?base-1:base+1);
549 int val=vorbis_dBquant(mask+x);
558 if(mdct[x]+info->twofitatten>=mask[x]){
559 if(y+info->maxover<val)return(1);
560 if(y-info->maxunder>val)return(1);
572 val=vorbis_dBquant(mask+x);
573 mse+=((y-val)*(y-val));
575 if(mdct[x]+info->twofitatten>=mask[x]){
577 if(y+info->maxover<val)return(1);
578 if(y-info->maxunder>val)return(1);
583 if(info->maxover*info->maxover/n>info->maxerr)return(0);
584 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
585 if(mse/n>info->maxerr)return(1);
589 static int post_Y(int *A,int *B,int pos){
595 return (A[pos]+B[pos])>>1;
600 int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
601 const float *logmdct, /* in */
602 const float *logmask){
604 vorbis_info_floor1 *info=look->vi;
606 long posts=look->posts;
608 lsfit_acc fits[VIF_POSIT+1];
609 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
610 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
612 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
613 int hineighbor[VIF_POSIT+2];
615 int memo[VIF_POSIT+2];
617 for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
618 for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
619 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
620 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
621 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
623 /* quantize the relevant floor points and collect them into line fit
624 structures (one per minimal division) at the same time */
626 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
628 for(i=0;i<posts-1;i++)
629 nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
630 look->sorted_index[i+1],fits+i,
635 /* start by fitting the implicit base case.... */
638 fit_line(fits,posts-1,&y0,&y1);
645 /* Non degenerate case */
646 /* start progressive splitting. This is a greedy, non-optimal
647 algorithm, but simple and close enough to the best
649 for(i=2;i<posts;i++){
650 int sortpos=look->reverse_index[i];
651 int ln=loneighbor[sortpos];
652 int hn=hineighbor[sortpos];
654 /* eliminate repeat searches of a particular range with a memo */
656 /* haven't performed this error search yet */
657 int lsortpos=look->reverse_index[ln];
658 int hsortpos=look->reverse_index[hn];
662 /* A note: we want to bound/minimize *local*, not global, error */
663 int lx=info->postlist[ln];
664 int hx=info->postlist[hn];
665 int ly=post_Y(fit_valueA,fit_valueB,ln);
666 int hy=post_Y(fit_valueA,fit_valueB,hn);
668 if(ly==-1 || hy==-1){
672 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
673 /* outside error bounds/begin search area. Split it. */
678 fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
679 fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
681 /* store new edge values */
683 if(ln==0)fit_valueA[ln]=ly0;
687 if(hn==1)fit_valueB[hn]=hy1;
689 if(ly1>=0 || hy0>=0){
690 /* store new neighbor values */
691 for(j=sortpos-1;j>=0;j--)
692 if(hineighbor[j]==hn)
696 for(j=sortpos+1;j<posts;j++)
697 if(loneighbor[j]==ln)
712 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
714 output[0]=post_Y(fit_valueA,fit_valueB,0);
715 output[1]=post_Y(fit_valueA,fit_valueB,1);
717 /* fill in posts marked as not using a fit; we will zero
718 back out to 'unused' when encoding them so long as curve
719 interpolation doesn't force them into use */
720 for(i=2;i<posts;i++){
721 int ln=look->loneighbor[i-2];
722 int hn=look->hineighbor[i-2];
723 int x0=info->postlist[ln];
724 int x1=info->postlist[hn];
728 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
729 int vx=post_Y(fit_valueA,fit_valueB,i);
731 if(vx>=0 && predicted!=vx){
734 output[i]= predicted|0x8000;
743 int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
748 long posts=look->posts;
752 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
754 for(i=0;i<posts;i++){
755 output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
756 if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
764 int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
765 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(opb,1,1);
850 /* beginning/end post */
852 look->postbits+=ilog(look->quant_q-1)*2;
853 oggpack_write(opb,out[0],ilog(look->quant_q-1));
854 oggpack_write(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,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(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(n,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