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 */
33 typedef struct lsfit_acc{
45 /***********************************************/
47 static void floor1_free_info(vorbis_info_floor *i){
48 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
50 memset(info,0,sizeof(*info));
55 static void floor1_free_look(vorbis_look_floor *i){
56 vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
58 /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n",
59 (float)look->phrasebits/look->frames,
60 (float)look->postbits/look->frames,
61 (float)(look->postbits+look->phrasebits)/look->frames);*/
63 memset(look,0,sizeof(*look));
68 static int ilog(unsigned int v){
77 static int ilog2(unsigned int v){
87 static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
88 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
92 int maxposit=info->postlist[1];
95 /* save out partitions */
96 oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */
97 for(j=0;j<info->partitions;j++){
98 oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */
99 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
102 /* save out partition classes */
103 for(j=0;j<maxclass+1;j++){
104 oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
105 oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
106 if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
107 for(k=0;k<(1<<info->class_subs[j]);k++)
108 oggpack_write(opb,info->class_subbook[j][k]+1,8);
111 /* save out the post list */
112 oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */
113 oggpack_write(opb,ilog2(maxposit),4);
114 rangebits=ilog2(maxposit);
116 for(j=0,k=0;j<info->partitions;j++){
117 count+=info->class_dim[info->partitionclass[j]];
119 oggpack_write(opb,info->postlist[k+2],rangebits);
124 static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
125 codec_setup_info *ci=vi->codec_setup;
126 int j,k,count=0,maxclass=-1,rangebits;
128 vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info));
129 /* read partitions */
130 info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
131 for(j=0;j<info->partitions;j++){
132 info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
133 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
136 /* read partition classes */
137 for(j=0;j<maxclass+1;j++){
138 info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
139 info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
140 if(info->class_subs[j]<0)
142 if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
143 if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
145 for(k=0;k<(1<<info->class_subs[j]);k++){
146 info->class_subbook[j][k]=oggpack_read(opb,8)-1;
147 if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
152 /* read the post list */
153 info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
154 rangebits=oggpack_read(opb,4);
156 for(j=0,k=0;j<info->partitions;j++){
157 count+=info->class_dim[info->partitionclass[j]];
159 int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
160 if(t<0 || t>=(1<<rangebits))
165 info->postlist[1]=1<<rangebits;
170 floor1_free_info(info);
174 static int icomp(const void *a,const void *b){
175 return(**(int **)a-**(int **)b);
178 static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,
179 vorbis_info_floor *in){
181 int *sortpointer[VIF_POSIT+2];
182 vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
183 vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(*look));
187 look->n=info->postlist[1];
189 /* we drop each position value in-between already decoded values,
190 and use linear interpolation to predict each new value past the
191 edges. The positions are read in the order of the position
192 list... we precompute the bounding positions in the lookup. Of
193 course, the neighbors can change (if a position is declined), but
194 this is an initial mapping */
196 for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
200 /* also store a sorted position index */
201 for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
202 qsort(sortpointer,n,sizeof(*sortpointer),icomp);
204 /* points from sort order back to range number */
205 for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
206 /* points from range order to sorted position */
207 for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
208 /* we actually need the post values too */
209 for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
211 /* quantize values to multiplier spec */
213 case 1: /* 1024 -> 256 */
216 case 2: /* 1024 -> 128 */
219 case 3: /* 1024 -> 86 */
222 case 4: /* 1024 -> 64 */
227 /* discover our neighbors for decode where we don't use fit flags
228 (that would push the neighbors outward) */
234 int currentx=info->postlist[i+2];
236 int x=info->postlist[j];
237 if(x>lx && x<currentx){
241 if(x<hx && x>currentx){
246 look->loneighbor[i]=lo;
247 look->hineighbor[i]=hi;
253 static int render_point(int x0,int x1,int y0,int y1,int x){
254 y0&=0x7fff; /* mask off flag */
264 if(dy<0)return(y0-off);
269 static int vorbis_dBquant(const float *x){
270 int i= *x*7.3142857f+1023.5f;
271 if(i>1023)return(1023);
276 static float FLOOR1_fromdB_LOOKUP[256]={
277 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
278 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
279 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
280 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
281 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
282 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
283 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
284 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
285 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
286 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
287 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
288 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
289 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
290 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
291 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
292 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
293 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
294 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
295 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
296 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
297 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
298 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
299 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
300 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
301 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
302 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
303 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
304 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
305 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
306 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
307 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
308 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
309 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
310 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
311 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
312 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
313 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
314 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
315 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
316 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
317 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
318 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
319 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
320 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
321 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
322 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
323 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
324 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
325 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
326 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
327 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
328 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
329 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
330 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
331 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
332 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
333 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
334 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
335 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
336 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
337 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
338 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
339 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
340 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
343 static void render_line(int n, int x0,int x1,int y0,int y1,float *d){
348 int sy=(dy<0?base-1:base+1);
358 d[x]*=FLOOR1_fromdB_LOOKUP[y];
368 d[x]*=FLOOR1_fromdB_LOOKUP[y];
372 static void render_line0(int x0,int x1,int y0,int y1,int *d){
377 int sy=(dy<0?base-1:base+1);
397 /* the floor has already been filtered to only include relevant sections */
398 static int accumulate_fit(const float *flr,const float *mdct,
399 int x0, int x1,lsfit_acc *a,
400 int n,vorbis_info_floor1 *info){
403 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;
405 memset(a,0,sizeof(*a));
411 int quantized=vorbis_dBquant(flr+i);
413 if(mdct[i]+info->twofitatten>=flr[i]){
417 y2a += quantized*quantized;
424 y2b += quantized*quantized;
438 /* weight toward the actually used frequencies if we meet the threshhold */
440 int weight=nb*info->twofitweight/(na+1);
444 a->x2a=x2a*weight+x2b;
445 a->y2a=y2a*weight+y2b;
446 a->xya=xya*weight+xyb;
453 static void fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
454 long x=0,y=0,x2=0,y2=0,xy=0,an=0,i;
456 long x1=a[fits-1].x1;
486 /* need 64 bit multiplies, which C doesn't give portably as int */
491 double denom=1./(an*fx2-fx*fx);
492 double a=(fy*fx2-fxy*fx)*denom;
493 double b=(an*fxy-fx*fy)*denom;
497 /* limit to our range! */
498 if(*y0>1023)*y0=1023;
499 if(*y1>1023)*y1=1023;
509 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
513 for(i=0;i<fits && y==0;i++)
519 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
521 vorbis_info_floor1 *info){
526 int sy=(dy<0?base-1:base+1);
530 int val=vorbis_dBquant(mask+x);
539 if(mdct[x]+info->twofitatten>=mask[x]){
540 if(y+info->maxover<val)return(1);
541 if(y-info->maxunder>val)return(1);
553 val=vorbis_dBquant(mask+x);
554 mse+=((y-val)*(y-val));
556 if(mdct[x]+info->twofitatten>=mask[x]){
558 if(y+info->maxover<val)return(1);
559 if(y-info->maxunder>val)return(1);
564 if(info->maxover*info->maxover/n>info->maxerr)return(0);
565 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
566 if(mse/n>info->maxerr)return(1);
570 static int post_Y(int *A,int *B,int pos){
576 return (A[pos]+B[pos])>>1;
579 int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
580 const float *logmdct, /* in */
581 const float *logmask){
583 vorbis_info_floor1 *info=look->vi;
585 long posts=look->posts;
587 lsfit_acc fits[VIF_POSIT+1];
588 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
589 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
591 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
592 int hineighbor[VIF_POSIT+2];
594 int memo[VIF_POSIT+2];
596 for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
597 for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
598 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
599 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
600 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
602 /* quantize the relevant floor points and collect them into line fit
603 structures (one per minimal division) at the same time */
605 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
607 for(i=0;i<posts-1;i++)
608 nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
609 look->sorted_index[i+1],fits+i,
614 /* start by fitting the implicit base case.... */
617 fit_line(fits,posts-1,&y0,&y1);
624 /* Non degenerate case */
625 /* start progressive splitting. This is a greedy, non-optimal
626 algorithm, but simple and close enough to the best
628 for(i=2;i<posts;i++){
629 int sortpos=look->reverse_index[i];
630 int ln=loneighbor[sortpos];
631 int hn=hineighbor[sortpos];
633 /* eliminate repeat searches of a particular range with a memo */
635 /* haven't performed this error search yet */
636 int lsortpos=look->reverse_index[ln];
637 int hsortpos=look->reverse_index[hn];
641 /* A note: we want to bound/minimize *local*, not global, error */
642 int lx=info->postlist[ln];
643 int hx=info->postlist[hn];
644 int ly=post_Y(fit_valueA,fit_valueB,ln);
645 int hy=post_Y(fit_valueA,fit_valueB,hn);
647 if(ly==-1 || hy==-1){
651 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
652 /* outside error bounds/begin search area. Split it. */
657 fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
658 fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
660 /* store new edge values */
662 if(ln==0)fit_valueA[ln]=ly0;
666 if(hn==1)fit_valueB[hn]=hy1;
668 if(ly1>=0 || hy0>=0){
669 /* store new neighbor values */
670 for(j=sortpos-1;j>=0;j--)
671 if(hineighbor[j]==hn)
675 for(j=sortpos+1;j<posts;j++)
676 if(loneighbor[j]==ln)
691 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
693 output[0]=post_Y(fit_valueA,fit_valueB,0);
694 output[1]=post_Y(fit_valueA,fit_valueB,1);
696 /* fill in posts marked as not using a fit; we will zero
697 back out to 'unused' when encoding them so long as curve
698 interpolation doesn't force them into use */
699 for(i=2;i<posts;i++){
700 int ln=look->loneighbor[i-2];
701 int hn=look->hineighbor[i-2];
702 int x0=info->postlist[ln];
703 int x1=info->postlist[hn];
707 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
708 int vx=post_Y(fit_valueA,fit_valueB,i);
710 if(vx>=0 && predicted!=vx){
713 output[i]= predicted|0x8000;
722 int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
727 long posts=look->posts;
731 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
733 for(i=0;i<posts;i++){
734 output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
735 if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
743 int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
744 vorbis_look_floor1 *look,
745 int *post,int *ilogmask){
748 vorbis_info_floor1 *info=look->vi;
749 long posts=look->posts;
750 codec_setup_info *ci=vb->vd->vi->codec_setup;
751 int out[VIF_POSIT+2];
752 static_codebook **sbooks=ci->book_param;
753 codebook *books=ci->fullbooks;
756 /* quantize values to multiplier spec */
758 for(i=0;i<posts;i++){
759 int val=post[i]&0x7fff;
761 case 1: /* 1024 -> 256 */
764 case 2: /* 1024 -> 128 */
767 case 3: /* 1024 -> 86 */
770 case 4: /* 1024 -> 64 */
774 post[i]=val | (post[i]&0x8000);
780 /* find prediction values for each post and subtract them */
781 for(i=2;i<posts;i++){
782 int ln=look->loneighbor[i-2];
783 int hn=look->hineighbor[i-2];
784 int x0=info->postlist[ln];
785 int x1=info->postlist[hn];
789 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
791 if((post[i]&0x8000) || (predicted==post[i])){
792 post[i]=predicted|0x8000; /* in case there was roundoff jitter
796 int headroom=(look->quant_q-predicted<predicted?
797 look->quant_q-predicted:predicted);
799 int val=post[i]-predicted;
801 /* at this point the 'deviation' value is in the range +/- max
802 range, but the real, unique range can always be mapped to
803 only [0-maxrange). So we want to wrap the deviation into
804 this limited range, but do it in the way that least screws
805 an essentially gaussian probability distribution. */
824 /* we have everything we need. pack it out */
825 /* mark nontrivial floor */
826 oggpack_write(opb,1,1);
828 /* beginning/end post */
830 look->postbits+=ilog(look->quant_q-1)*2;
831 oggpack_write(opb,out[0],ilog(look->quant_q-1));
832 oggpack_write(opb,out[1],ilog(look->quant_q-1));
835 /* partition by partition */
836 for(i=0,j=2;i<info->partitions;i++){
837 int class=info->partitionclass[i];
838 int cdim=info->class_dim[class];
839 int csubbits=info->class_subs[class];
840 int csub=1<<csubbits;
841 int bookas[8]={0,0,0,0,0,0,0,0};
846 /* generate the partition's first stage cascade value */
850 int booknum=info->class_subbook[class][k];
854 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
865 cval|= bookas[k]<<cshift;
870 vorbis_book_encode(books+info->class_book[class],cval,opb);
876 sprintf(buffer,"line_%dx%ld_class%d.vqd",
877 vb->pcmend/2,posts-2,class);
878 of=fopen(buffer,"a");
879 fprintf(of,"%d\n",cval);
885 /* write post values */
887 int book=info->class_subbook[class][bookas[k]];
889 /* hack to allow training with 'bad' books */
890 if(out[j+k]<(books+book)->entries)
891 look->postbits+=vorbis_book_encode(books+book,
894 fprintf(stderr,"+!");*/
900 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
901 vb->pcmend/2,posts-2,class,bookas[k]);
902 of=fopen(buffer,"a");
903 fprintf(of,"%d\n",out[j+k]);
913 /* generate quantized floor equivalent to what we'd unpack in decode */
914 /* render the lines */
917 int ly=post[0]*info->mult;
918 for(j=1;j<look->posts;j++){
919 int current=look->forward_index[j];
920 int hy=post[current]&0x7fff;
921 if(hy==post[current]){
924 hx=info->postlist[current];
926 render_line0(lx,hx,ly,hy,ilogmask);
932 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
937 oggpack_write(opb,0,1);
938 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
944 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
945 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
946 vorbis_info_floor1 *info=look->vi;
947 codec_setup_info *ci=vb->vd->vi->codec_setup;
950 codebook *books=ci->fullbooks;
952 /* unpack wrapped/predicted values from stream */
953 if(oggpack_read(&vb->opb,1)==1){
954 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
956 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
957 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
959 /* partition by partition */
960 for(i=0,j=2;i<info->partitions;i++){
961 int class=info->partitionclass[i];
962 int cdim=info->class_dim[class];
963 int csubbits=info->class_subs[class];
964 int csub=1<<csubbits;
967 /* decode the partition's first stage cascade value */
969 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
971 if(cval==-1)goto eop;
975 int book=info->class_subbook[class][cval&(csub-1)];
978 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
987 /* unwrap positive values and reconsitute via linear interpolation */
988 for(i=2;i<look->posts;i++){
989 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
990 info->postlist[look->hineighbor[i-2]],
991 fit_value[look->loneighbor[i-2]],
992 fit_value[look->hineighbor[i-2]],
994 int hiroom=look->quant_q-predicted;
995 int loroom=predicted;
996 int room=(hiroom<loroom?hiroom:loroom)<<1;
997 int val=fit_value[i];
1004 val = -1-(val-hiroom);
1014 fit_value[i]=val+predicted;
1015 fit_value[look->loneighbor[i-2]]&=0x7fff;
1016 fit_value[look->hineighbor[i-2]]&=0x7fff;
1019 fit_value[i]=predicted|0x8000;
1030 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1032 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1033 vorbis_info_floor1 *info=look->vi;
1035 codec_setup_info *ci=vb->vd->vi->codec_setup;
1036 int n=ci->blocksizes[vb->W]/2;
1040 /* render the lines */
1041 int *fit_value=(int *)memo;
1044 int ly=fit_value[0]*info->mult;
1045 for(j=1;j<look->posts;j++){
1046 int current=look->forward_index[j];
1047 int hy=fit_value[current]&0x7fff;
1048 if(hy==fit_value[current]){
1051 hx=info->postlist[current];
1053 render_line(n,lx,hx,ly,hy,out);
1059 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1062 memset(out,0,sizeof(*out)*n);
1067 vorbis_func_floor floor1_exportbundle={
1068 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
1069 &floor1_free_look,&floor1_inverse1,&floor1_inverse2