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){
402 int quantized=vorbis_dBquant(flr+x0);
404 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;
406 memset(a,0,sizeof(*a));
412 int quantized=vorbis_dBquant(flr+i);
414 if(mdct[i]+info->twofitatten>=flr[i]){
418 y2a += quantized*quantized;
425 y2b += quantized*quantized;
439 /* weight toward the actually used frequencies if we meet the threshhold */
441 int weight=nb*info->twofitweight/(na+1);
445 a->x2a=x2a*weight+x2b;
446 a->y2a=y2a*weight+y2b;
447 a->xya=xya*weight+xyb;
454 static void fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
455 long x=0,y=0,x2=0,y2=0,xy=0,an=0,i;
457 long x1=a[fits-1].x1;
487 /* need 64 bit multiplies, which C doesn't give portably as int */
492 double denom=1./(an*fx2-fx*fx);
493 double a=(fy*fx2-fxy*fx)*denom;
494 double b=(an*fxy-fx*fy)*denom;
498 /* limit to our range! */
499 if(*y0>1023)*y0=1023;
500 if(*y1>1023)*y1=1023;
510 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
514 for(i=0;i<fits && y==0;i++)
520 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
522 vorbis_info_floor1 *info){
527 int sy=(dy<0?base-1:base+1);
531 int val=vorbis_dBquant(mask+x);
540 if(mdct[x]+info->twofitatten>=mask[x]){
541 if(y+info->maxover<val)return(1);
542 if(y-info->maxunder>val)return(1);
554 val=vorbis_dBquant(mask+x);
555 mse+=((y-val)*(y-val));
557 if(mdct[x]+info->twofitatten>=mask[x]){
559 if(y+info->maxover<val)return(1);
560 if(y-info->maxunder>val)return(1);
565 if(info->maxover*info->maxover/n>info->maxerr)return(0);
566 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
567 if(mse/n>info->maxerr)return(1);
571 static int post_Y(int *A,int *B,int pos){
577 return (A[pos]+B[pos])>>1;
582 int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
583 const float *logmdct, /* in */
584 const float *logmask){
586 vorbis_info_floor1 *info=look->vi;
588 long posts=look->posts;
590 lsfit_acc fits[VIF_POSIT+1];
591 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
592 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
594 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
595 int hineighbor[VIF_POSIT+2];
597 int memo[VIF_POSIT+2];
599 for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
600 for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
601 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
602 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
603 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
605 /* quantize the relevant floor points and collect them into line fit
606 structures (one per minimal division) at the same time */
608 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
610 for(i=0;i<posts-1;i++)
611 nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
612 look->sorted_index[i+1],fits+i,
617 /* start by fitting the implicit base case.... */
620 fit_line(fits,posts-1,&y0,&y1);
627 /* Non degenerate case */
628 /* start progressive splitting. This is a greedy, non-optimal
629 algorithm, but simple and close enough to the best
631 for(i=2;i<posts;i++){
632 int sortpos=look->reverse_index[i];
633 int ln=loneighbor[sortpos];
634 int hn=hineighbor[sortpos];
636 /* eliminate repeat searches of a particular range with a memo */
638 /* haven't performed this error search yet */
639 int lsortpos=look->reverse_index[ln];
640 int hsortpos=look->reverse_index[hn];
644 /* A note: we want to bound/minimize *local*, not global, error */
645 int lx=info->postlist[ln];
646 int hx=info->postlist[hn];
647 int ly=post_Y(fit_valueA,fit_valueB,ln);
648 int hy=post_Y(fit_valueA,fit_valueB,hn);
650 if(ly==-1 || hy==-1){
654 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
655 /* outside error bounds/begin search area. Split it. */
660 fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
661 fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
663 /* store new edge values */
665 if(ln==0)fit_valueA[ln]=ly0;
669 if(hn==1)fit_valueB[hn]=hy1;
671 if(ly1>=0 || hy0>=0){
672 /* store new neighbor values */
673 for(j=sortpos-1;j>=0;j--)
674 if(hineighbor[j]==hn)
678 for(j=sortpos+1;j<posts;j++)
679 if(loneighbor[j]==ln)
694 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
696 output[0]=post_Y(fit_valueA,fit_valueB,0);
697 output[1]=post_Y(fit_valueA,fit_valueB,1);
699 /* fill in posts marked as not using a fit; we will zero
700 back out to 'unused' when encoding them so long as curve
701 interpolation doesn't force them into use */
702 for(i=2;i<posts;i++){
703 int ln=look->loneighbor[i-2];
704 int hn=look->hineighbor[i-2];
705 int x0=info->postlist[ln];
706 int x1=info->postlist[hn];
710 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
711 int vx=post_Y(fit_valueA,fit_valueB,i);
713 if(vx>=0 && predicted!=vx){
716 output[i]= predicted|0x8000;
725 int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
730 long posts=look->posts;
734 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
736 for(i=0;i<posts;i++){
737 output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
738 if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
746 int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
747 vorbis_look_floor1 *look,
748 int *post,int *ilogmask){
751 vorbis_info_floor1 *info=look->vi;
753 long posts=look->posts;
754 codec_setup_info *ci=vb->vd->vi->codec_setup;
755 int out[VIF_POSIT+2];
756 static_codebook **sbooks=ci->book_param;
757 codebook *books=ci->fullbooks;
760 /* quantize values to multiplier spec */
762 for(i=0;i<posts;i++){
763 int val=post[i]&0x7fff;
765 case 1: /* 1024 -> 256 */
768 case 2: /* 1024 -> 128 */
771 case 3: /* 1024 -> 86 */
774 case 4: /* 1024 -> 64 */
778 post[i]=val | (post[i]&0x8000);
784 /* find prediction values for each post and subtract them */
785 for(i=2;i<posts;i++){
786 int ln=look->loneighbor[i-2];
787 int hn=look->hineighbor[i-2];
788 int x0=info->postlist[ln];
789 int x1=info->postlist[hn];
793 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
795 if((post[i]&0x8000) || (predicted==post[i])){
796 post[i]=predicted|0x8000; /* in case there was roundoff jitter
800 int headroom=(look->quant_q-predicted<predicted?
801 look->quant_q-predicted:predicted);
803 int val=post[i]-predicted;
805 /* at this point the 'deviation' value is in the range +/- max
806 range, but the real, unique range can always be mapped to
807 only [0-maxrange). So we want to wrap the deviation into
808 this limited range, but do it in the way that least screws
809 an essentially gaussian probability distribution. */
828 /* we have everything we need. pack it out */
829 /* mark nontrivial floor */
830 oggpack_write(opb,1,1);
832 /* beginning/end post */
834 look->postbits+=ilog(look->quant_q-1)*2;
835 oggpack_write(opb,out[0],ilog(look->quant_q-1));
836 oggpack_write(opb,out[1],ilog(look->quant_q-1));
839 /* partition by partition */
840 for(i=0,j=2;i<info->partitions;i++){
841 int class=info->partitionclass[i];
842 int cdim=info->class_dim[class];
843 int csubbits=info->class_subs[class];
844 int csub=1<<csubbits;
845 int bookas[8]={0,0,0,0,0,0,0,0};
850 /* generate the partition's first stage cascade value */
854 int booknum=info->class_subbook[class][k];
858 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
869 cval|= bookas[k]<<cshift;
874 vorbis_book_encode(books+info->class_book[class],cval,opb);
880 sprintf(buffer,"line_%dx%ld_class%d.vqd",
881 vb->pcmend/2,posts-2,class);
882 of=fopen(buffer,"a");
883 fprintf(of,"%d\n",cval);
889 /* write post values */
891 int book=info->class_subbook[class][bookas[k]];
893 /* hack to allow training with 'bad' books */
894 if(out[j+k]<(books+book)->entries)
895 look->postbits+=vorbis_book_encode(books+book,
898 fprintf(stderr,"+!");*/
904 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
905 vb->pcmend/2,posts-2,class,bookas[k]);
906 of=fopen(buffer,"a");
907 fprintf(of,"%d\n",out[j+k]);
917 /* generate quantized floor equivalent to what we'd unpack in decode */
918 /* render the lines */
921 int ly=post[0]*info->mult;
922 for(j=1;j<look->posts;j++){
923 int current=look->forward_index[j];
924 int hy=post[current]&0x7fff;
925 if(hy==post[current]){
928 hx=info->postlist[current];
930 render_line0(lx,hx,ly,hy,ilogmask);
936 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
941 oggpack_write(opb,0,1);
942 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
948 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
949 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
950 vorbis_info_floor1 *info=look->vi;
951 codec_setup_info *ci=vb->vd->vi->codec_setup;
954 codebook *books=ci->fullbooks;
956 /* unpack wrapped/predicted values from stream */
957 if(oggpack_read(&vb->opb,1)==1){
958 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
960 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
961 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
963 /* partition by partition */
964 for(i=0,j=2;i<info->partitions;i++){
965 int class=info->partitionclass[i];
966 int cdim=info->class_dim[class];
967 int csubbits=info->class_subs[class];
968 int csub=1<<csubbits;
971 /* decode the partition's first stage cascade value */
973 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
975 if(cval==-1)goto eop;
979 int book=info->class_subbook[class][cval&(csub-1)];
982 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
991 /* unwrap positive values and reconsitute via linear interpolation */
992 for(i=2;i<look->posts;i++){
993 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
994 info->postlist[look->hineighbor[i-2]],
995 fit_value[look->loneighbor[i-2]],
996 fit_value[look->hineighbor[i-2]],
998 int hiroom=look->quant_q-predicted;
999 int loroom=predicted;
1000 int room=(hiroom<loroom?hiroom:loroom)<<1;
1001 int val=fit_value[i];
1008 val = -1-(val-hiroom);
1018 fit_value[i]=val+predicted;
1019 fit_value[look->loneighbor[i-2]]&=0x7fff;
1020 fit_value[look->hineighbor[i-2]]&=0x7fff;
1023 fit_value[i]=predicted|0x8000;
1034 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1036 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1037 vorbis_info_floor1 *info=look->vi;
1039 codec_setup_info *ci=vb->vd->vi->codec_setup;
1040 int n=ci->blocksizes[vb->W]/2;
1044 /* render the lines */
1045 int *fit_value=(int *)memo;
1048 int ly=fit_value[0]*info->mult;
1049 for(j=1;j<look->posts;j++){
1050 int current=look->forward_index[j];
1051 int hy=fit_value[current]&0x7fff;
1052 if(hy==fit_value[current]){
1055 hx=info->postlist[current];
1057 render_line(n,lx,hx,ly,hy,out);
1063 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1066 memset(out,0,sizeof(*out)*n);
1071 vorbis_func_floor floor1_exportbundle={
1072 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
1073 &floor1_free_look,&floor1_inverse1,&floor1_inverse2