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;
755 /* quantize values to multiplier spec */
757 for(i=0;i<posts;i++){
758 int val=post[i]&0x7fff;
760 case 1: /* 1024 -> 256 */
763 case 2: /* 1024 -> 128 */
766 case 3: /* 1024 -> 86 */
769 case 4: /* 1024 -> 64 */
773 post[i]=val | (post[i]&0x8000);
779 /* find prediction values for each post and subtract them */
780 for(i=2;i<posts;i++){
781 int ln=look->loneighbor[i-2];
782 int hn=look->hineighbor[i-2];
783 int x0=info->postlist[ln];
784 int x1=info->postlist[hn];
788 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
790 if((post[i]&0x8000) || (predicted==post[i])){
791 post[i]=predicted|0x8000; /* in case there was roundoff jitter
795 int headroom=(look->quant_q-predicted<predicted?
796 look->quant_q-predicted:predicted);
798 int val=post[i]-predicted;
800 /* at this point the 'deviation' value is in the range +/- max
801 range, but the real, unique range can always be mapped to
802 only [0-maxrange). So we want to wrap the deviation into
803 this limited range, but do it in the way that least screws
804 an essentially gaussian probability distribution. */
823 /* we have everything we need. pack it out */
824 /* mark nontrivial floor */
825 oggpack_write(opb,1,1);
827 /* beginning/end post */
829 look->postbits+=ilog(look->quant_q-1)*2;
830 oggpack_write(opb,out[0],ilog(look->quant_q-1));
831 oggpack_write(opb,out[1],ilog(look->quant_q-1));
834 /* partition by partition */
835 for(i=0,j=2;i<info->partitions;i++){
836 int class=info->partitionclass[i];
837 int cdim=info->class_dim[class];
838 int csubbits=info->class_subs[class];
839 int csub=1<<csubbits;
840 int bookas[8]={0,0,0,0,0,0,0,0};
845 /* generate the partition's first stage cascade value */
849 int booknum=info->class_subbook[class][k];
853 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
864 cval|= bookas[k]<<cshift;
869 vorbis_book_encode(books+info->class_book[class],cval,opb);
875 sprintf(buffer,"line_%dx%ld_class%d.vqd",
876 vb->pcmend/2,posts-2,class);
877 of=fopen(buffer,"a");
878 fprintf(of,"%d\n",cval);
884 /* write post values */
886 int book=info->class_subbook[class][bookas[k]];
888 /* hack to allow training with 'bad' books */
889 if(out[j+k]<(books+book)->entries)
890 look->postbits+=vorbis_book_encode(books+book,
893 fprintf(stderr,"+!");*/
899 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
900 vb->pcmend/2,posts-2,class,bookas[k]);
901 of=fopen(buffer,"a");
902 fprintf(of,"%d\n",out[j+k]);
912 /* generate quantized floor equivalent to what we'd unpack in decode */
913 /* render the lines */
916 int ly=post[0]*info->mult;
917 for(j=1;j<look->posts;j++){
918 int current=look->forward_index[j];
919 int hy=post[current]&0x7fff;
920 if(hy==post[current]){
923 hx=info->postlist[current];
925 render_line0(lx,hx,ly,hy,ilogmask);
931 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
935 oggpack_write(opb,0,1);
936 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
941 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
942 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
943 vorbis_info_floor1 *info=look->vi;
944 codec_setup_info *ci=vb->vd->vi->codec_setup;
947 codebook *books=ci->fullbooks;
949 /* unpack wrapped/predicted values from stream */
950 if(oggpack_read(&vb->opb,1)==1){
951 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
953 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
954 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
956 /* partition by partition */
957 for(i=0,j=2;i<info->partitions;i++){
958 int class=info->partitionclass[i];
959 int cdim=info->class_dim[class];
960 int csubbits=info->class_subs[class];
961 int csub=1<<csubbits;
964 /* decode the partition's first stage cascade value */
966 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
968 if(cval==-1)goto eop;
972 int book=info->class_subbook[class][cval&(csub-1)];
975 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
984 /* unwrap positive values and reconsitute via linear interpolation */
985 for(i=2;i<look->posts;i++){
986 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
987 info->postlist[look->hineighbor[i-2]],
988 fit_value[look->loneighbor[i-2]],
989 fit_value[look->hineighbor[i-2]],
991 int hiroom=look->quant_q-predicted;
992 int loroom=predicted;
993 int room=(hiroom<loroom?hiroom:loroom)<<1;
994 int val=fit_value[i];
1001 val = -1-(val-hiroom);
1011 fit_value[i]=val+predicted;
1012 fit_value[look->loneighbor[i-2]]&=0x7fff;
1013 fit_value[look->hineighbor[i-2]]&=0x7fff;
1016 fit_value[i]=predicted|0x8000;
1027 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1029 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1030 vorbis_info_floor1 *info=look->vi;
1032 codec_setup_info *ci=vb->vd->vi->codec_setup;
1033 int n=ci->blocksizes[vb->W]/2;
1037 /* render the lines */
1038 int *fit_value=(int *)memo;
1041 int ly=fit_value[0]*info->mult;
1042 for(j=1;j<look->posts;j++){
1043 int current=look->forward_index[j];
1044 int hy=fit_value[current]&0x7fff;
1045 if(hy==fit_value[current]){
1048 hx=info->postlist[current];
1050 render_line(n,lx,hx,ly,hy,out);
1056 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1059 memset(out,0,sizeof(*out)*n);
1064 vorbis_func_floor floor1_exportbundle={
1065 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
1066 &floor1_free_look,&floor1_inverse1,&floor1_inverse2