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 const 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 int 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 */
489 double denom=(an*fx2-fx*fx);
495 double a=(fy*fx2-fxy*fx)/denom;
496 double b=(an*fxy-fx*fy)/denom;
500 /* limit to our range! */
501 if(*y0>1023)*y0=1023;
502 if(*y1>1023)*y1=1023;
515 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
519 for(i=0;i<fits && y==0;i++)
525 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
527 vorbis_info_floor1 *info){
532 int sy=(dy<0?base-1:base+1);
536 int val=vorbis_dBquant(mask+x);
545 if(mdct[x]+info->twofitatten>=mask[x]){
546 if(y+info->maxover<val)return(1);
547 if(y-info->maxunder>val)return(1);
559 val=vorbis_dBquant(mask+x);
560 mse+=((y-val)*(y-val));
562 if(mdct[x]+info->twofitatten>=mask[x]){
564 if(y+info->maxover<val)return(1);
565 if(y-info->maxunder>val)return(1);
570 if(info->maxover*info->maxover/n>info->maxerr)return(0);
571 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
572 if(mse/n>info->maxerr)return(1);
576 static int post_Y(int *A,int *B,int pos){
582 return (A[pos]+B[pos])>>1;
585 int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
586 const float *logmdct, /* in */
587 const float *logmask){
589 vorbis_info_floor1 *info=look->vi;
591 long posts=look->posts;
593 lsfit_acc fits[VIF_POSIT+1];
594 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
595 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
597 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
598 int hineighbor[VIF_POSIT+2];
600 int memo[VIF_POSIT+2];
602 for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
603 for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
604 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
605 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
606 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
608 /* quantize the relevant floor points and collect them into line fit
609 structures (one per minimal division) at the same time */
611 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
613 for(i=0;i<posts-1;i++)
614 nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
615 look->sorted_index[i+1],fits+i,
620 /* start by fitting the implicit base case.... */
623 fit_line(fits,posts-1,&y0,&y1);
630 /* Non degenerate case */
631 /* start progressive splitting. This is a greedy, non-optimal
632 algorithm, but simple and close enough to the best
634 for(i=2;i<posts;i++){
635 int sortpos=look->reverse_index[i];
636 int ln=loneighbor[sortpos];
637 int hn=hineighbor[sortpos];
639 /* eliminate repeat searches of a particular range with a memo */
641 /* haven't performed this error search yet */
642 int lsortpos=look->reverse_index[ln];
643 int hsortpos=look->reverse_index[hn];
647 /* A note: we want to bound/minimize *local*, not global, error */
648 int lx=info->postlist[ln];
649 int hx=info->postlist[hn];
650 int ly=post_Y(fit_valueA,fit_valueB,ln);
651 int hy=post_Y(fit_valueA,fit_valueB,hn);
653 if(ly==-1 || hy==-1){
657 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
658 /* outside error bounds/begin search area. Split it. */
663 int ret0=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
664 int ret1=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
679 /* store new edge values */
681 if(ln==0)fit_valueA[ln]=ly0;
685 if(hn==1)fit_valueB[hn]=hy1;
687 if(ly1>=0 || hy0>=0){
688 /* store new neighbor values */
689 for(j=sortpos-1;j>=0;j--)
690 if(hineighbor[j]==hn)
694 for(j=sortpos+1;j<posts;j++)
695 if(loneighbor[j]==ln)
709 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
711 output[0]=post_Y(fit_valueA,fit_valueB,0);
712 output[1]=post_Y(fit_valueA,fit_valueB,1);
714 /* fill in posts marked as not using a fit; we will zero
715 back out to 'unused' when encoding them so long as curve
716 interpolation doesn't force them into use */
717 for(i=2;i<posts;i++){
718 int ln=look->loneighbor[i-2];
719 int hn=look->hineighbor[i-2];
720 int x0=info->postlist[ln];
721 int x1=info->postlist[hn];
725 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
726 int vx=post_Y(fit_valueA,fit_valueB,i);
728 if(vx>=0 && predicted!=vx){
731 output[i]= predicted|0x8000;
740 int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
745 long posts=look->posts;
749 output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
751 /* overly simpleminded--- look again post 1.2 */
752 for(i=0;i<posts;i++){
753 output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
754 if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
762 int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
763 vorbis_look_floor1 *look,
764 int *post,int *ilogmask){
767 vorbis_info_floor1 *info=look->vi;
768 long posts=look->posts;
769 codec_setup_info *ci=vb->vd->vi->codec_setup;
770 int out[VIF_POSIT+2];
771 static_codebook **sbooks=ci->book_param;
772 codebook *books=ci->fullbooks;
774 /* quantize values to multiplier spec */
776 for(i=0;i<posts;i++){
777 int val=post[i]&0x7fff;
779 case 1: /* 1024 -> 256 */
782 case 2: /* 1024 -> 128 */
785 case 3: /* 1024 -> 86 */
788 case 4: /* 1024 -> 64 */
792 post[i]=val | (post[i]&0x8000);
798 /* find prediction values for each post and subtract them */
799 for(i=2;i<posts;i++){
800 int ln=look->loneighbor[i-2];
801 int hn=look->hineighbor[i-2];
802 int x0=info->postlist[ln];
803 int x1=info->postlist[hn];
807 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
809 if((post[i]&0x8000) || (predicted==post[i])){
810 post[i]=predicted|0x8000; /* in case there was roundoff jitter
814 int headroom=(look->quant_q-predicted<predicted?
815 look->quant_q-predicted:predicted);
817 int val=post[i]-predicted;
819 /* at this point the 'deviation' value is in the range +/- max
820 range, but the real, unique range can always be mapped to
821 only [0-maxrange). So we want to wrap the deviation into
822 this limited range, but do it in the way that least screws
823 an essentially gaussian probability distribution. */
842 /* we have everything we need. pack it out */
843 /* mark nontrivial floor */
844 oggpack_write(opb,1,1);
846 /* beginning/end post */
848 look->postbits+=ilog(look->quant_q-1)*2;
849 oggpack_write(opb,out[0],ilog(look->quant_q-1));
850 oggpack_write(opb,out[1],ilog(look->quant_q-1));
853 /* partition by partition */
854 for(i=0,j=2;i<info->partitions;i++){
855 int class=info->partitionclass[i];
856 int cdim=info->class_dim[class];
857 int csubbits=info->class_subs[class];
858 int csub=1<<csubbits;
859 int bookas[8]={0,0,0,0,0,0,0,0};
864 /* generate the partition's first stage cascade value */
868 int booknum=info->class_subbook[class][k];
872 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
883 cval|= bookas[k]<<cshift;
888 vorbis_book_encode(books+info->class_book[class],cval,opb);
894 sprintf(buffer,"line_%dx%ld_class%d.vqd",
895 vb->pcmend/2,posts-2,class);
896 of=fopen(buffer,"a");
897 fprintf(of,"%d\n",cval);
903 /* write post values */
905 int book=info->class_subbook[class][bookas[k]];
907 /* hack to allow training with 'bad' books */
908 if(out[j+k]<(books+book)->entries)
909 look->postbits+=vorbis_book_encode(books+book,
912 fprintf(stderr,"+!");*/
918 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
919 vb->pcmend/2,posts-2,class,bookas[k]);
920 of=fopen(buffer,"a");
921 fprintf(of,"%d\n",out[j+k]);
931 /* generate quantized floor equivalent to what we'd unpack in decode */
932 /* render the lines */
935 int ly=post[0]*info->mult;
936 for(j=1;j<look->posts;j++){
937 int current=look->forward_index[j];
938 int hy=post[current]&0x7fff;
939 if(hy==post[current]){
942 hx=info->postlist[current];
944 render_line0(lx,hx,ly,hy,ilogmask);
950 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
954 oggpack_write(opb,0,1);
955 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
960 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
961 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
962 vorbis_info_floor1 *info=look->vi;
963 codec_setup_info *ci=vb->vd->vi->codec_setup;
966 codebook *books=ci->fullbooks;
968 /* unpack wrapped/predicted values from stream */
969 if(oggpack_read(&vb->opb,1)==1){
970 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
972 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
973 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
975 /* partition by partition */
976 for(i=0,j=2;i<info->partitions;i++){
977 int class=info->partitionclass[i];
978 int cdim=info->class_dim[class];
979 int csubbits=info->class_subs[class];
980 int csub=1<<csubbits;
983 /* decode the partition's first stage cascade value */
985 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
987 if(cval==-1)goto eop;
991 int book=info->class_subbook[class][cval&(csub-1)];
994 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1003 /* unwrap positive values and reconsitute via linear interpolation */
1004 for(i=2;i<look->posts;i++){
1005 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1006 info->postlist[look->hineighbor[i-2]],
1007 fit_value[look->loneighbor[i-2]],
1008 fit_value[look->hineighbor[i-2]],
1010 int hiroom=look->quant_q-predicted;
1011 int loroom=predicted;
1012 int room=(hiroom<loroom?hiroom:loroom)<<1;
1013 int val=fit_value[i];
1020 val = -1-(val-hiroom);
1030 fit_value[i]=val+predicted;
1031 fit_value[look->loneighbor[i-2]]&=0x7fff;
1032 fit_value[look->hineighbor[i-2]]&=0x7fff;
1035 fit_value[i]=predicted|0x8000;
1046 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1048 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1049 vorbis_info_floor1 *info=look->vi;
1051 codec_setup_info *ci=vb->vd->vi->codec_setup;
1052 int n=ci->blocksizes[vb->W]/2;
1056 /* render the lines */
1057 int *fit_value=(int *)memo;
1060 int ly=fit_value[0]*info->mult;
1061 for(j=1;j<look->posts;j++){
1062 int current=look->forward_index[j];
1063 int hy=fit_value[current]&0x7fff;
1064 if(hy==fit_value[current]){
1067 hx=info->postlist[current];
1069 render_line(n,lx,hx,ly,hy,out);
1075 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1078 memset(out,0,sizeof(*out)*n);
1083 const vorbis_func_floor floor1_exportbundle={
1084 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
1085 &floor1_free_look,&floor1_inverse1,&floor1_inverse2