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-2009 *
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);
123 static int icomp(const void *a,const void *b){
124 return(**(int **)a-**(int **)b);
127 static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
128 codec_setup_info *ci=vi->codec_setup;
129 int j,k,count=0,maxclass=-1,rangebits;
131 vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info));
132 /* read partitions */
133 info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
134 for(j=0;j<info->partitions;j++){
135 info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
136 if(info->partitionclass[j]<0)goto err_out;
137 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
140 /* read partition classes */
141 for(j=0;j<maxclass+1;j++){
142 info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
143 info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
144 if(info->class_subs[j]<0)
146 if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
147 if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
149 for(k=0;k<(1<<info->class_subs[j]);k++){
150 info->class_subbook[j][k]=oggpack_read(opb,8)-1;
151 if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
156 /* read the post list */
157 info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
158 rangebits=oggpack_read(opb,4);
159 if(rangebits<0)goto err_out;
161 for(j=0,k=0;j<info->partitions;j++){
162 count+=info->class_dim[info->partitionclass[j]];
164 int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
165 if(t<0 || t>=(1<<rangebits))
170 info->postlist[1]=1<<rangebits;
172 /* don't allow repeated values in post list as they'd result in
173 zero-length segments */
175 int *sortpointer[VIF_POSIT+2];
176 for(j=0;j<count+2;j++)sortpointer[j]=info->postlist+j;
177 qsort(sortpointer,count+2,sizeof(*sortpointer),icomp);
179 for(j=1;j<count+2;j++)
180 if(*sortpointer[j-1]==*sortpointer[j])goto err_out;
186 floor1_free_info(info);
190 static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,
191 vorbis_info_floor *in){
193 int *sortpointer[VIF_POSIT+2];
194 vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
195 vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(*look));
199 look->n=info->postlist[1];
201 /* we drop each position value in-between already decoded values,
202 and use linear interpolation to predict each new value past the
203 edges. The positions are read in the order of the position
204 list... we precompute the bounding positions in the lookup. Of
205 course, the neighbors can change (if a position is declined), but
206 this is an initial mapping */
208 for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
212 /* also store a sorted position index */
213 for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
214 qsort(sortpointer,n,sizeof(*sortpointer),icomp);
216 /* points from sort order back to range number */
217 for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
218 /* points from range order to sorted position */
219 for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
220 /* we actually need the post values too */
221 for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
223 /* quantize values to multiplier spec */
225 case 1: /* 1024 -> 256 */
228 case 2: /* 1024 -> 128 */
231 case 3: /* 1024 -> 86 */
234 case 4: /* 1024 -> 64 */
239 /* discover our neighbors for decode where we don't use fit flags
240 (that would push the neighbors outward) */
246 int currentx=info->postlist[i+2];
248 int x=info->postlist[j];
249 if(x>lx && x<currentx){
253 if(x<hx && x>currentx){
258 look->loneighbor[i]=lo;
259 look->hineighbor[i]=hi;
265 static int render_point(int x0,int x1,int y0,int y1,int x){
266 y0&=0x7fff; /* mask off flag */
276 if(dy<0)return(y0-off);
281 static int vorbis_dBquant(const float *x){
282 int i= *x*7.3142857f+1023.5f;
283 if(i>1023)return(1023);
288 static const float FLOOR1_fromdB_LOOKUP[256]={
289 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
290 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
291 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
292 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
293 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
294 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
295 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
296 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
297 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
298 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
299 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
300 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
301 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
302 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
303 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
304 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
305 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
306 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
307 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
308 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
309 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
310 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
311 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
312 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
313 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
314 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
315 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
316 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
317 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
318 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
319 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
320 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
321 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
322 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
323 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
324 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
325 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
326 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
327 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
328 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
329 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
330 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
331 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
332 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
333 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
334 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
335 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
336 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
337 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
338 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
339 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
340 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
341 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
342 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
343 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
344 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
345 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
346 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
347 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
348 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
349 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
350 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
351 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
352 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
355 static void render_line(int n, int x0,int x1,int y0,int y1,float *d){
360 int sy=(dy<0?base-1:base+1);
370 d[x]*=FLOOR1_fromdB_LOOKUP[y];
380 d[x]*=FLOOR1_fromdB_LOOKUP[y];
384 static void render_line0(int n, int x0,int x1,int y0,int y1,int *d){
389 int sy=(dy<0?base-1:base+1);
413 /* the floor has already been filtered to only include relevant sections */
414 static int accumulate_fit(const float *flr,const float *mdct,
415 int x0, int x1,lsfit_acc *a,
416 int n,vorbis_info_floor1 *info){
419 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;
421 memset(a,0,sizeof(*a));
427 int quantized=vorbis_dBquant(flr+i);
429 if(mdct[i]+info->twofitatten>=flr[i]){
433 y2a += quantized*quantized;
440 y2b += quantized*quantized;
454 /* weight toward the actually used frequencies if we meet the threshhold */
456 int weight=nb*info->twofitweight/(na+1);
460 a->x2a=x2a*weight+x2b;
461 a->y2a=y2a*weight+y2b;
462 a->xya=xya*weight+xyb;
469 static int fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
470 long x=0,y=0,x2=0,y2=0,xy=0,an=0,i;
472 long x1=a[fits-1].x1;
502 /* need 64 bit multiplies, which C doesn't give portably as int */
505 double denom=(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;
531 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
535 for(i=0;i<fits && y==0;i++)
541 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
543 vorbis_info_floor1 *info){
548 int sy=(dy<0?base-1:base+1);
552 int val=vorbis_dBquant(mask+x);
561 if(mdct[x]+info->twofitatten>=mask[x]){
562 if(y+info->maxover<val)return(1);
563 if(y-info->maxunder>val)return(1);
575 val=vorbis_dBquant(mask+x);
576 mse+=((y-val)*(y-val));
578 if(mdct[x]+info->twofitatten>=mask[x]){
580 if(y+info->maxover<val)return(1);
581 if(y-info->maxunder>val)return(1);
586 if(info->maxover*info->maxover/n>info->maxerr)return(0);
587 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
588 if(mse/n>info->maxerr)return(1);
592 static int post_Y(int *A,int *B,int pos){
598 return (A[pos]+B[pos])>>1;
601 int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
602 const float *logmdct, /* in */
603 const float *logmask){
605 vorbis_info_floor1 *info=look->vi;
607 long posts=look->posts;
609 lsfit_acc fits[VIF_POSIT+1];
610 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
611 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
613 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
614 int hineighbor[VIF_POSIT+2];
616 int memo[VIF_POSIT+2];
618 for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
619 for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
620 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
621 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
622 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
624 /* quantize the relevant floor points and collect them into line fit
625 structures (one per minimal division) at the same time */
627 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
629 for(i=0;i<posts-1;i++)
630 nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
631 look->sorted_index[i+1],fits+i,
636 /* start by fitting the implicit base case.... */
639 fit_line(fits,posts-1,&y0,&y1);
646 /* Non degenerate case */
647 /* start progressive splitting. This is a greedy, non-optimal
648 algorithm, but simple and close enough to the best
650 for(i=2;i<posts;i++){
651 int sortpos=look->reverse_index[i];
652 int ln=loneighbor[sortpos];
653 int hn=hineighbor[sortpos];
655 /* eliminate repeat searches of a particular range with a memo */
657 /* haven't performed this error search yet */
658 int lsortpos=look->reverse_index[ln];
659 int hsortpos=look->reverse_index[hn];
663 /* A note: we want to bound/minimize *local*, not global, error */
664 int lx=info->postlist[ln];
665 int hx=info->postlist[hn];
666 int ly=post_Y(fit_valueA,fit_valueB,ln);
667 int hy=post_Y(fit_valueA,fit_valueB,hn);
669 if(ly==-1 || hy==-1){
673 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
674 /* outside error bounds/begin search area. Split it. */
679 int ret0=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
680 int ret1=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
695 /* store new edge values */
697 if(ln==0)fit_valueA[ln]=ly0;
701 if(hn==1)fit_valueB[hn]=hy1;
703 if(ly1>=0 || hy0>=0){
704 /* store new neighbor values */
705 for(j=sortpos-1;j>=0;j--)
706 if(hineighbor[j]==hn)
710 for(j=sortpos+1;j<posts;j++)
711 if(loneighbor[j]==ln)
725 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
727 output[0]=post_Y(fit_valueA,fit_valueB,0);
728 output[1]=post_Y(fit_valueA,fit_valueB,1);
730 /* fill in posts marked as not using a fit; we will zero
731 back out to 'unused' when encoding them so long as curve
732 interpolation doesn't force them into use */
733 for(i=2;i<posts;i++){
734 int ln=look->loneighbor[i-2];
735 int hn=look->hineighbor[i-2];
736 int x0=info->postlist[ln];
737 int x1=info->postlist[hn];
741 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
742 int vx=post_Y(fit_valueA,fit_valueB,i);
744 if(vx>=0 && predicted!=vx){
747 output[i]= predicted|0x8000;
756 int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
761 long posts=look->posts;
765 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
767 /* overly simpleminded--- look again post 1.2 */
768 for(i=0;i<posts;i++){
769 output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
770 if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
778 int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
779 vorbis_look_floor1 *look,
780 int *post,int *ilogmask){
783 vorbis_info_floor1 *info=look->vi;
784 long posts=look->posts;
785 codec_setup_info *ci=vb->vd->vi->codec_setup;
786 int out[VIF_POSIT+2];
787 static_codebook **sbooks=ci->book_param;
788 codebook *books=ci->fullbooks;
790 /* quantize values to multiplier spec */
792 for(i=0;i<posts;i++){
793 int val=post[i]&0x7fff;
795 case 1: /* 1024 -> 256 */
798 case 2: /* 1024 -> 128 */
801 case 3: /* 1024 -> 86 */
804 case 4: /* 1024 -> 64 */
808 post[i]=val | (post[i]&0x8000);
814 /* find prediction values for each post and subtract them */
815 for(i=2;i<posts;i++){
816 int ln=look->loneighbor[i-2];
817 int hn=look->hineighbor[i-2];
818 int x0=info->postlist[ln];
819 int x1=info->postlist[hn];
823 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
825 if((post[i]&0x8000) || (predicted==post[i])){
826 post[i]=predicted|0x8000; /* in case there was roundoff jitter
830 int headroom=(look->quant_q-predicted<predicted?
831 look->quant_q-predicted:predicted);
833 int val=post[i]-predicted;
835 /* at this point the 'deviation' value is in the range +/- max
836 range, but the real, unique range can always be mapped to
837 only [0-maxrange). So we want to wrap the deviation into
838 this limited range, but do it in the way that least screws
839 an essentially gaussian probability distribution. */
858 /* we have everything we need. pack it out */
859 /* mark nontrivial floor */
860 oggpack_write(opb,1,1);
862 /* beginning/end post */
864 look->postbits+=ilog(look->quant_q-1)*2;
865 oggpack_write(opb,out[0],ilog(look->quant_q-1));
866 oggpack_write(opb,out[1],ilog(look->quant_q-1));
869 /* partition by partition */
870 for(i=0,j=2;i<info->partitions;i++){
871 int class=info->partitionclass[i];
872 int cdim=info->class_dim[class];
873 int csubbits=info->class_subs[class];
874 int csub=1<<csubbits;
875 int bookas[8]={0,0,0,0,0,0,0,0};
880 /* generate the partition's first stage cascade value */
884 int booknum=info->class_subbook[class][k];
888 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
899 cval|= bookas[k]<<cshift;
904 vorbis_book_encode(books+info->class_book[class],cval,opb);
910 sprintf(buffer,"line_%dx%ld_class%d.vqd",
911 vb->pcmend/2,posts-2,class);
912 of=fopen(buffer,"a");
913 fprintf(of,"%d\n",cval);
919 /* write post values */
921 int book=info->class_subbook[class][bookas[k]];
923 /* hack to allow training with 'bad' books */
924 if(out[j+k]<(books+book)->entries)
925 look->postbits+=vorbis_book_encode(books+book,
928 fprintf(stderr,"+!");*/
934 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
935 vb->pcmend/2,posts-2,class,bookas[k]);
936 of=fopen(buffer,"a");
937 fprintf(of,"%d\n",out[j+k]);
947 /* generate quantized floor equivalent to what we'd unpack in decode */
948 /* render the lines */
951 int ly=post[0]*info->mult;
952 int n=ci->blocksizes[vb->W]/2;
954 for(j=1;j<look->posts;j++){
955 int current=look->forward_index[j];
956 int hy=post[current]&0x7fff;
957 if(hy==post[current]){
960 hx=info->postlist[current];
962 render_line0(n,lx,hx,ly,hy,ilogmask);
968 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
972 oggpack_write(opb,0,1);
973 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
978 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
979 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
980 vorbis_info_floor1 *info=look->vi;
981 codec_setup_info *ci=vb->vd->vi->codec_setup;
984 codebook *books=ci->fullbooks;
986 /* unpack wrapped/predicted values from stream */
987 if(oggpack_read(&vb->opb,1)==1){
988 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
990 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
991 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
993 /* partition by partition */
994 for(i=0,j=2;i<info->partitions;i++){
995 int class=info->partitionclass[i];
996 int cdim=info->class_dim[class];
997 int csubbits=info->class_subs[class];
998 int csub=1<<csubbits;
1001 /* decode the partition's first stage cascade value */
1003 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
1005 if(cval==-1)goto eop;
1008 for(k=0;k<cdim;k++){
1009 int book=info->class_subbook[class][cval&(csub-1)];
1012 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1021 /* unwrap positive values and reconsitute via linear interpolation */
1022 for(i=2;i<look->posts;i++){
1023 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1024 info->postlist[look->hineighbor[i-2]],
1025 fit_value[look->loneighbor[i-2]],
1026 fit_value[look->hineighbor[i-2]],
1028 int hiroom=look->quant_q-predicted;
1029 int loroom=predicted;
1030 int room=(hiroom<loroom?hiroom:loroom)<<1;
1031 int val=fit_value[i];
1038 val = -1-(val-hiroom);
1048 fit_value[i]=val+predicted;
1049 fit_value[look->loneighbor[i-2]]&=0x7fff;
1050 fit_value[look->hineighbor[i-2]]&=0x7fff;
1053 fit_value[i]=predicted|0x8000;
1064 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1066 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1067 vorbis_info_floor1 *info=look->vi;
1069 codec_setup_info *ci=vb->vd->vi->codec_setup;
1070 int n=ci->blocksizes[vb->W]/2;
1074 /* render the lines */
1075 int *fit_value=(int *)memo;
1078 int ly=fit_value[0]*info->mult;
1079 for(j=1;j<look->posts;j++){
1080 int current=look->forward_index[j];
1081 int hy=fit_value[current]&0x7fff;
1082 if(hy==fit_value[current]){
1085 hx=info->postlist[current];
1087 render_line(n,lx,hx,ly,hy,out);
1093 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1096 memset(out,0,sizeof(*out)*n);
1101 const vorbis_func_floor floor1_exportbundle={
1102 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
1103 &floor1_free_look,&floor1_inverse1,&floor1_inverse2