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-2001 *
9 * by the XIPHOPHORUS Company http://www.xiph.org/ *
11 ********************************************************************
13 function: floor backend 1 implementation
14 last mod: $Id: floor1.c,v 1.2 2001/05/27 06:44:00 xiphmont Exp $
16 ********************************************************************/
22 #include "vorbis/codec.h"
23 #include "codec_internal.h"
31 #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
34 int sorted_index[VIF_POSIT+2];
35 int forward_index[VIF_POSIT+2];
36 int reverse_index[VIF_POSIT+2];
38 int hineighbor[VIF_POSIT];
39 int loneighbor[VIF_POSIT];
44 vorbis_info_floor1 *vi;
54 typedef struct lsfit_acc{
70 /***********************************************/
72 static vorbis_info_floor *floor1_copy_info (vorbis_info_floor *i){
73 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
74 vorbis_info_floor1 *ret=_ogg_malloc(sizeof(vorbis_info_floor1));
75 memcpy(ret,info,sizeof(vorbis_info_floor1));
79 static void floor1_free_info(vorbis_info_floor *i){
81 memset(i,0,sizeof(vorbis_info_floor1));
86 static void floor1_free_look(vorbis_look_floor *i){
87 vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
89 fprintf(stderr,"floor 1 bit usage: %ld:%ld:%ld (%ld/frame), mse:%gdB\n",
90 look->postbits/look->seq,look->classbits/look->seq,look->subbits/look->seq,
91 (look->postbits+look->subbits+look->classbits)/look->seq,
92 sqrt(look->mse/look->seq));
94 memset(look,0,sizeof(vorbis_look_floor1));
99 static int ilog(unsigned int v){
108 static int ilog2(unsigned int v){
117 static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
118 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
122 int maxposit=info->postlist[1];
125 /* save out partitions */
126 oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */
127 for(j=0;j<info->partitions;j++){
128 oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */
129 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
132 /* save out partition classes */
133 for(j=0;j<maxclass+1;j++){
134 oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
135 oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
136 if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
137 for(k=0;k<(1<<info->class_subs[j]);k++)
138 oggpack_write(opb,info->class_subbook[j][k]+1,8);
141 /* save out the post list */
142 oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */
143 oggpack_write(opb,ilog2(maxposit),4);
144 rangebits=ilog2(maxposit);
146 for(j=0,k=0;j<info->partitions;j++){
147 count+=info->class_dim[info->partitionclass[j]];
149 oggpack_write(opb,info->postlist[k+2],rangebits);
154 static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
155 codec_setup_info *ci=vi->codec_setup;
156 int j,k,count=0,maxclass=-1,rangebits;
158 vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(vorbis_info_floor1));
159 /* read partitions */
160 info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
161 for(j=0;j<info->partitions;j++){
162 info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
163 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
166 /* read partition classes */
167 for(j=0;j<maxclass+1;j++){
168 info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
169 info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
170 if(info->class_subs[j]<0)
172 if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
173 if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
175 for(k=0;k<(1<<info->class_subs[j]);k++){
176 info->class_subbook[j][k]=oggpack_read(opb,8)-1;
177 if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
182 /* read the post list */
183 info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
184 rangebits=oggpack_read(opb,4);
186 for(j=0,k=0;j<info->partitions;j++){
187 count+=info->class_dim[info->partitionclass[j]];
189 int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
190 if(t<0 || t>=(1<<rangebits))
195 info->postlist[1]=1<<rangebits;
200 floor1_free_info(info);
204 static int icomp(const void *a,const void *b){
205 return(**(int **)a-**(int **)b);
208 static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,vorbis_info_mode *mi,
209 vorbis_info_floor *in){
211 int *sortpointer[VIF_POSIT+2];
212 vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
213 vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(vorbis_look_floor1));
217 look->n=info->postlist[1];
219 /* we drop each position value in-between already decoded values,
220 and use linear interpolation to predict each new value past the
221 edges. The positions are read in the order of the position
222 list... we precompute the bounding positions in the lookup. Of
223 course, the neighbors can change (if a position is declined), but
224 this is an initial mapping */
226 for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
230 /* also store a sorted position index */
231 for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
232 qsort(sortpointer,n,sizeof(int),icomp);
234 /* points from sort order back to range number */
235 for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
236 /* points from range order to sorted position */
237 for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
238 /* we actually need the post values too */
239 for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
241 /* quantize values to multiplier spec */
243 case 1: /* 1024 -> 256 */
246 case 2: /* 1024 -> 128 */
249 case 3: /* 1024 -> 86 */
252 case 4: /* 1024 -> 64 */
257 /* discover our neighbors for decode where we don't use fit flags
258 (that would push the neighbors outward) */
264 int currentx=info->postlist[i+2];
266 int x=info->postlist[j];
267 if(x>lx && x<currentx){
271 if(x<hx && x>currentx){
276 look->loneighbor[i]=lo;
277 look->hineighbor[i]=hi;
283 static int render_point(int x0,int x1,int y0,int y1,int x){
284 y0&=0x7fff; /* mask off flag */
294 if(dy<0)return(y0-off);
299 static int vorbis_dBquant(const float *x){
300 int i= *x*7.3142857f+1023.5f;
301 if(i>1023)return(1023);
306 static float FLOOR_fromdB_LOOKUP[256]={
307 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
308 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
309 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
310 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
311 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
312 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
313 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
314 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
315 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
316 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
317 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
318 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
319 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
320 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
321 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
322 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
323 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
324 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
325 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
326 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
327 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
328 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
329 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
330 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
331 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
332 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
333 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
334 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
335 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
336 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
337 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
338 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
339 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
340 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
341 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
342 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
343 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
344 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
345 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
346 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
347 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
348 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
349 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
350 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
351 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
352 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
353 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
354 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
355 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
356 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
357 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
358 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
359 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
360 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
361 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
362 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
363 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
364 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
365 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
366 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
367 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
368 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
369 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
370 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
373 static void render_line(int x0,int x1,int y0,int y1,float *d){
378 int sy=(dy<0?base-1:base+1);
385 d[x]=FLOOR_fromdB_LOOKUP[y];
394 d[x]=FLOOR_fromdB_LOOKUP[y];
398 /* the floor has already been filtered to only include relevant sections */
399 static int accumulate_fit(const float *flr,const float *mdct,
400 int x0, int x1,lsfit_acc *a,
401 int n,vorbis_info_floor1 *info){
403 int quantized=vorbis_dBquant(flr);
405 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;
407 memset(a,0,sizeof(lsfit_acc));
414 int quantized=vorbis_dBquant(flr+i);
416 if(mdct[i]+info->twofitatten>=flr[i]){
420 y2a += quantized*quantized;
427 y2b += quantized*quantized;
441 /* weight toward the actually used frequencies if we meet the threshhold */
444 if(nb<info->twofitminsize || na<info->twofitminused){
447 weight=nb*info->twofitweight/na;
451 a->x2a=x2a*weight+x2b;
452 a->y2a=y2a*weight+y2b;
453 a->xya=xya*weight+xyb;
457 if(nb>=info->unusedminsize)a->un++;
462 int quantized=vorbis_dBquant(flr+i);
468 /* returns < 0 on too few points to fit, >=0 (meansq error) on success */
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,n=0,an=0,i;
472 long x1=a[fits-1].x1;
486 if(*y0>=0){ /* hint used to break degenerate cases */
496 if(*y1>=0){ /* hint used to break degenerate cases */
509 /* need 64 bit multiplies, which C doesn't give portably as int */
515 double denom=1./(an*fx2-fx*fx);
516 double a=(fy*fx2-fxy*fx)*denom;
517 double b=(an*fxy-fx*fy)*denom;
521 /* limit to our range! */
522 if(*y0>1023)*y0=1023;
523 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);
558 if(mdct[x]+info->twofitatten>=mask[x]){
559 if(y+info->maxover<val)return(1);
560 if(y-info->maxunder>val)return(1);
575 if(mdct[x]+info->twofitatten>=mask[x]){
576 val=vorbis_dBquant(mask+x);
578 if(y+info->maxover<val)return(1);
579 if(y-info->maxunder>val)return(1);
580 mse+=((y-val)*(y-val));
587 if(info->maxover*info->maxover/n>info->maxerr)return(0);
588 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
589 if(mse/n>info->maxerr)return(1);
594 static int post_Y(int *A,int *B,int pos){
599 return (A[pos]+B[pos])>>1;
602 static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
603 const float *mdct, const float *logmdct, /* in */
604 const float *logmask, const float *logmax, /* in */
605 float *residue, float *codedflr){ /* out */
608 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
609 vorbis_info_floor1 *info=look->vi;
611 long posts=look->posts;
613 lsfit_acc fits[VIF_POSIT+1];
614 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
615 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
616 int fit_flag[VIF_POSIT+2];
618 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
619 int hineighbor[VIF_POSIT+2];
620 int memo[VIF_POSIT+2];
621 codec_setup_info *ci=vb->vd->vi->codec_setup;
622 static_codebook **sbooks=ci->book_param;
623 codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
626 memset(fit_flag,0,sizeof(fit_flag));
627 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
628 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
629 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
631 /* Scan back from high edge to first 'used' frequency */
632 for(;n>info->unusedmin_n;n--)
633 if(logmdct[n-1]>-floor1_rangedB &&
634 logmdct[n-1]+info->twofitatten>logmask[n-1])break;
636 /* quantize the relevant floor points and collect them into line fit
637 structures (one per minimal division) at the same time */
639 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
641 for(i=0;i<posts-1;i++)
642 nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
643 look->sorted_index[i+1],fits+i,
648 /* start by fitting the implicit base case.... */
651 int mse=fit_line(fits,posts-1,&y0,&y1);
653 /* Only a single nonzero point */
656 fit_line(fits,posts-1,&y0,&y1);
669 /* Non degenerate case */
670 /* start progressive splitting. This is a greedy, non-optimal
671 algorithm, but simple and close enough to the best
673 for(i=2;i<posts;i++){
674 int sortpos=look->reverse_index[i];
675 int ln=loneighbor[sortpos];
676 int hn=hineighbor[sortpos];
678 /* eliminate repeat searches of a particular range with a memo */
680 /* haven't performed this error search yet */
681 int lsortpos=look->reverse_index[ln];
682 int hsortpos=look->reverse_index[hn];
685 /* if this is an empty segment, its endpoints don't matter.
687 for(j=lsortpos;j<hsortpos;j++)
690 /* empty segment; important to note that this does not
691 break 0/n post case */
700 /* A note: we want to bound/minimize *local*, not global, error */
701 int lx=info->postlist[ln];
702 int hx=info->postlist[hn];
703 int ly=post_Y(fit_valueA,fit_valueB,ln);
704 int hy=post_Y(fit_valueA,fit_valueB,hn);
706 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
707 /* outside error bounds/begin search area. Split it. */
712 int lmse=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
713 int hmse=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
715 /* the boundary/sparsity cases are the hard part. They
716 don't happen often given that we use the full mask
717 curve (weighted) now, but when they do happen they
718 can go boom. Pay them detailed attention */
719 /* cases for a segment:
720 >=0) normal fit (>=2 unique points)
722 one point on x1; <-- disallowed by fit_line
723 -2) one point in between x0 and x1
728 /* no points in the low segment */
731 ly0=fits[lsortpos].edgey0;
738 /* no points in the hi segment */
741 hy0=fits[sortpos].edgey0;
745 /* store new edge values */
747 if(ln==0 && ly0>=0)fit_valueA[ln]=ly0;
751 if(hn==1 && hy1>=0)fit_valueB[hn]=hy1;
753 if(ly0<0 && fit_valueA[ln]<0)
755 if(hy1<0 && fit_valueB[hn]<0)
758 if(ly1>=0 || hy0>=0){
759 /* store new neighbor values */
760 for(j=sortpos-1;j>=0;j--)
761 if(hineighbor[j]==hn)
765 for(j=sortpos+1;j<posts;j++)
766 if(loneighbor[j]==ln)
771 /* store flag (set) */
780 /* quantize values to multiplier spec */
782 case 1: /* 1024 -> 256 */
785 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>2;
787 case 2: /* 1024 -> 128 */
790 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>3;
792 case 3: /* 1024 -> 86 */
795 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)/12;
797 case 4: /* 1024 -> 64 */
800 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>4;
804 /* find prediction values for each post and subtract them */
805 for(i=2;i<posts;i++){
806 int sp=look->reverse_index[i];
807 int ln=look->loneighbor[i-2];
808 int hn=look->hineighbor[i-2];
809 int x0=info->postlist[ln];
810 int x1=info->postlist[hn];
811 int y0=fit_valueA[ln];
812 int y1=fit_valueA[hn];
814 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
817 int headroom=(look->quant_q-predicted<predicted?
818 look->quant_q-predicted:predicted);
820 int val=fit_valueA[i]-predicted;
822 /* at this point the 'deviation' value is in the range +/- max
823 range, but the real, unique range can always be mapped to
824 only [0-maxrange). So we want to wrap the deviation into
825 this limited range, but do it in the way that least screws
826 an essentially gaussian probability distribution. */
841 /* unroll the neighbor arrays */
842 for(j=sp+1;j<posts;j++)
844 loneighbor[j]=loneighbor[sp];
849 hineighbor[j]=hineighbor[sp];
854 fit_valueA[i]=predicted;
859 /* we have everything we need. pack it out */
860 /* mark nontrivial floor */
861 oggpack_write(&vb->opb,1,1);
863 /* beginning/end post */
864 look->postbits+=ilog(look->quant_q-1)*2;
865 oggpack_write(&vb->opb,fit_valueA[0],ilog(look->quant_q-1));
866 oggpack_write(&vb->opb,fit_valueA[1],ilog(look->quant_q-1));
872 sprintf(buffer,"line%d_full.vqd",vb->mode);
873 of=fopen(buffer,"a");
875 fprintf(of,"%d\n",fit_valueB[j]);
881 /* partition by partition */
882 for(i=0,j=2;i<info->partitions;i++){
883 int class=info->partitionclass[i];
884 int cdim=info->class_dim[class];
885 int csubbits=info->class_subs[class];
886 int csub=1<<csubbits;
887 int bookas[8]={0,0,0,0,0,0,0,0};
891 /* generate the partition's first stage cascade value */
895 int booknum=info->class_subbook[class][k];
899 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
904 int val=fit_valueB[j+k];
910 cval|= bookas[k]<<cshift;
914 look->classbits+=vorbis_book_encode(books+info->class_book[class],cval,&vb->opb);
920 sprintf(buffer,"line%d_class%d.vqd",vb->mode,class);
921 of=fopen(buffer,"a");
922 fprintf(of,"%d\n",cval);
928 /* write post values */
930 int book=info->class_subbook[class][bookas[k]];
932 look->subbits+=vorbis_book_encode(books+book,
933 fit_valueB[j+k],&vb->opb);
939 sprintf(buffer,"line%d_%dsub%d.vqd",vb->mode,class,bookas[k]);
940 of=fopen(buffer,"a");
941 fprintf(of,"%d\n",fit_valueB[j+k]);
951 /* generate quantized floor equivalent to what we'd unpack in decode */
954 int ly=fit_valueA[0]*info->mult;
955 for(j=1;j<posts;j++){
956 int current=look->forward_index[j];
957 if(fit_valueB[current]>0){
958 int hy=fit_valueA[current]*info->mult;
959 hx=info->postlist[current];
961 render_line(lx,hx,ly,hy,codedflr);
967 for(j=hx;j<look->n;j++)codedflr[j]=codedflr[j-1]; /* be certain */
969 /* use it to create residue vector. Eliminate residue elements
970 that were below the error training attenuation relative to
971 the original mask. This avoids portions of the floor fit
972 that were considered 'unused' in fitting from being used in
973 coding residue if the unfit values are significantly below
974 the original input mask */
976 if(logmdct[j]+info->twofitatten<logmask[j])
979 residue[j]=mdct[j]/codedflr[j];
980 for(j=n;j<look->n;j++)residue[j]=0.f;
985 oggpack_write(&vb->opb,0,1);
986 memset(codedflr,0,n*sizeof(float));
992 static int floor1_inverse(vorbis_block *vb,vorbis_look_floor *in,float *out){
993 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
994 vorbis_info_floor1 *info=look->vi;
996 codec_setup_info *ci=vb->vd->vi->codec_setup;
997 int n=ci->blocksizes[vb->mode]/2;
999 codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
1002 /* unpack wrapped/predicted values from stream */
1003 if(oggpack_read(&vb->opb,1)==1){
1004 int fit_value[VIF_POSIT+2];
1006 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
1007 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
1009 /* partition by partition */
1010 /* partition by partition */
1011 for(i=0,j=2;i<info->partitions;i++){
1012 int class=info->partitionclass[i];
1013 int cdim=info->class_dim[class];
1014 int csubbits=info->class_subs[class];
1015 int csub=1<<csubbits;
1018 /* decode the partition's first stage cascade value */
1020 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
1022 if(cval==-1)goto eop;
1025 for(k=0;k<cdim;k++){
1026 int book=info->class_subbook[class][cval&(csub-1)];
1029 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1038 /* unwrap positive values and reconsitute via linear interpolation */
1039 for(i=2;i<look->posts;i++){
1040 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1041 info->postlist[look->hineighbor[i-2]],
1042 fit_value[look->loneighbor[i-2]],
1043 fit_value[look->hineighbor[i-2]],
1045 int hiroom=look->quant_q-predicted;
1046 int loroom=predicted;
1047 int room=(hiroom<loroom?hiroom:loroom)<<1;
1048 int val=fit_value[i];
1055 val = -1-(val-hiroom);
1065 fit_value[i]=val+predicted;
1067 fit_value[i]=predicted|0x8000;
1072 /* render the lines */
1076 int ly=fit_value[0]*info->mult;
1077 for(j=1;j<look->posts;j++){
1078 int current=look->forward_index[j];
1079 int hy=fit_value[current]&0x7fff;
1080 if(hy==fit_value[current]){
1083 hx=info->postlist[current];
1085 render_line(lx,hx,ly,hy,out);
1091 for(j=hx;j<n;j++)out[j]=out[j-1]; /* be certain */
1098 memset(out,0,sizeof(float)*n);
1103 vorbis_func_floor floor1_exportbundle={
1104 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_copy_info,&floor1_free_info,
1105 &floor1_free_look,&floor1_forward,&floor1_inverse