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.10 2001/06/15 23:59:47 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;
48 typedef struct lsfit_acc{
64 /***********************************************/
66 static vorbis_info_floor *floor1_copy_info (vorbis_info_floor *i){
67 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
68 vorbis_info_floor1 *ret=_ogg_malloc(sizeof(vorbis_info_floor1));
69 memcpy(ret,info,sizeof(vorbis_info_floor1));
73 static void floor1_free_info(vorbis_info_floor *i){
75 memset(i,0,sizeof(vorbis_info_floor1));
80 static void floor1_free_look(vorbis_look_floor *i){
81 vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
83 memset(look,0,sizeof(vorbis_look_floor1));
88 static int ilog(unsigned int v){
97 static int ilog2(unsigned int v){
106 static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
107 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
111 int maxposit=info->postlist[1];
114 /* save out partitions */
115 oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */
116 for(j=0;j<info->partitions;j++){
117 oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */
118 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
121 /* save out partition classes */
122 for(j=0;j<maxclass+1;j++){
123 oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
124 oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
125 if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
126 for(k=0;k<(1<<info->class_subs[j]);k++)
127 oggpack_write(opb,info->class_subbook[j][k]+1,8);
130 /* save out the post list */
131 oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */
132 oggpack_write(opb,ilog2(maxposit),4);
133 rangebits=ilog2(maxposit);
135 for(j=0,k=0;j<info->partitions;j++){
136 count+=info->class_dim[info->partitionclass[j]];
138 oggpack_write(opb,info->postlist[k+2],rangebits);
143 static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
144 codec_setup_info *ci=vi->codec_setup;
145 int j,k,count=0,maxclass=-1,rangebits;
147 vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(vorbis_info_floor1));
148 /* read partitions */
149 info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
150 for(j=0;j<info->partitions;j++){
151 info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
152 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
155 /* read partition classes */
156 for(j=0;j<maxclass+1;j++){
157 info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
158 info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
159 if(info->class_subs[j]<0)
161 if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
162 if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
164 for(k=0;k<(1<<info->class_subs[j]);k++){
165 info->class_subbook[j][k]=oggpack_read(opb,8)-1;
166 if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
171 /* read the post list */
172 info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
173 rangebits=oggpack_read(opb,4);
175 for(j=0,k=0;j<info->partitions;j++){
176 count+=info->class_dim[info->partitionclass[j]];
178 int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
179 if(t<0 || t>=(1<<rangebits))
184 info->postlist[1]=1<<rangebits;
189 floor1_free_info(info);
193 static int icomp(const void *a,const void *b){
194 return(**(int **)a-**(int **)b);
197 static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,vorbis_info_mode *mi,
198 vorbis_info_floor *in){
200 int *sortpointer[VIF_POSIT+2];
201 vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
202 vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(vorbis_look_floor1));
206 look->n=info->postlist[1];
208 /* we drop each position value in-between already decoded values,
209 and use linear interpolation to predict each new value past the
210 edges. The positions are read in the order of the position
211 list... we precompute the bounding positions in the lookup. Of
212 course, the neighbors can change (if a position is declined), but
213 this is an initial mapping */
215 for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
219 /* also store a sorted position index */
220 for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
221 qsort(sortpointer,n,sizeof(int),icomp);
223 /* points from sort order back to range number */
224 for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
225 /* points from range order to sorted position */
226 for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
227 /* we actually need the post values too */
228 for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
230 /* quantize values to multiplier spec */
232 case 1: /* 1024 -> 256 */
235 case 2: /* 1024 -> 128 */
238 case 3: /* 1024 -> 86 */
241 case 4: /* 1024 -> 64 */
246 /* discover our neighbors for decode where we don't use fit flags
247 (that would push the neighbors outward) */
253 int currentx=info->postlist[i+2];
255 int x=info->postlist[j];
256 if(x>lx && x<currentx){
260 if(x<hx && x>currentx){
265 look->loneighbor[i]=lo;
266 look->hineighbor[i]=hi;
272 static int render_point(int x0,int x1,int y0,int y1,int x){
273 y0&=0x7fff; /* mask off flag */
283 if(dy<0)return(y0-off);
288 static int vorbis_dBquant(const float *x){
289 int i= *x*7.3142857f+1023.5f;
290 if(i>1023)return(1023);
295 static float FLOOR_fromdB_LOOKUP[256]={
296 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
297 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
298 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
299 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
300 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
301 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
302 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
303 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
304 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
305 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
306 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
307 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
308 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
309 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
310 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
311 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
312 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
313 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
314 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
315 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
316 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
317 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
318 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
319 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
320 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
321 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
322 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
323 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
324 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
325 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
326 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
327 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
328 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
329 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
330 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
331 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
332 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
333 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
334 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
335 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
336 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
337 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
338 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
339 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
340 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
341 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
342 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
343 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
344 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
345 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
346 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
347 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
348 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
349 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
350 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
351 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
352 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
353 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
354 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
355 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
356 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
357 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
358 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
359 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
362 static void render_line(int x0,int x1,int y0,int y1,float *d){
367 int sy=(dy<0?base-1:base+1);
374 d[x]*=FLOOR_fromdB_LOOKUP[y];
383 d[x]*=FLOOR_fromdB_LOOKUP[y];
387 static void render_line0(int x0,int x1,int y0,int y1,float *d){
392 int sy=(dy<0?base-1:base+1);
399 d[x]=FLOOR_fromdB_LOOKUP[y];
408 d[x]=FLOOR_fromdB_LOOKUP[y];
412 /* the floor has already been filtered to only include relevant sections */
413 static int accumulate_fit(const float *flr,const float *mdct,
414 int x0, int x1,lsfit_acc *a,
415 int n,vorbis_info_floor1 *info){
417 int quantized=vorbis_dBquant(flr);
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(lsfit_acc));
428 int quantized=vorbis_dBquant(flr+i);
430 if(mdct[i]+info->twofitatten>=flr[i]){
434 y2a += quantized*quantized;
441 y2b += quantized*quantized;
455 /* weight toward the actually used frequencies if we meet the threshhold */
458 if(nb<info->twofitminsize || na<info->twofitminused){
461 weight=nb*info->twofitweight/na;
465 a->x2a=x2a*weight+x2b;
466 a->y2a=y2a*weight+y2b;
467 a->xya=xya*weight+xyb;
471 if(nb>=info->unusedminsize)a->un++;
476 int quantized=vorbis_dBquant(flr+i);
482 /* returns < 0 on too few points to fit, >=0 (meansq error) on success */
483 static int fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
484 long x=0,y=0,x2=0,y2=0,xy=0,n=0,an=0,i;
486 long x1=a[fits-1].x1;
500 if(*y0>=0){ /* hint used to break degenerate cases */
510 if(*y1>=0){ /* hint used to break degenerate cases */
523 /* need 64 bit multiplies, which C doesn't give portably as int */
528 double denom=1./(an*fx2-fx*fx);
529 double a=(fy*fx2-fxy*fx)*denom;
530 double b=(an*fxy-fx*fy)*denom;
534 /* limit to our range! */
535 if(*y0>1023)*y0=1023;
536 if(*y1>1023)*y1=1023;
544 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
548 for(i=0;i<fits && y==0;i++)
554 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
556 vorbis_info_floor1 *info){
561 int sy=(dy<0?base-1:base+1);
565 int val=vorbis_dBquant(mask+x);
571 if(mdct[x]+info->twofitatten>=mask[x]){
572 if(y+info->maxover<val)return(1);
573 if(y-info->maxunder>val)return(1);
588 if(mdct[x]+info->twofitatten>=mask[x]){
589 val=vorbis_dBquant(mask+x);
591 if(y+info->maxover<val)return(1);
592 if(y-info->maxunder>val)return(1);
593 mse+=((y-val)*(y-val));
600 if(info->maxover*info->maxover/n>info->maxerr)return(0);
601 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
602 if(mse/n>info->maxerr)return(1);
607 static int post_Y(int *A,int *B,int pos){
612 return (A[pos]+B[pos])>>1;
615 static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
616 const float *mdct, const float *logmdct, /* in */
617 const float *logmask, const float *logmax, /* in */
618 float *residue, float *codedflr){ /* out */
621 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
622 vorbis_info_floor1 *info=look->vi;
624 long posts=look->posts;
626 lsfit_acc fits[VIF_POSIT+1];
627 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
628 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
629 int fit_flag[VIF_POSIT+2];
631 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
632 int hineighbor[VIF_POSIT+2];
633 int memo[VIF_POSIT+2];
634 codec_setup_info *ci=vb->vd->vi->codec_setup;
635 static_codebook **sbooks=ci->book_param;
636 codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
639 memset(fit_flag,0,sizeof(fit_flag));
640 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
641 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
642 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
644 /* Scan back from high edge to first 'used' frequency */
645 for(;n>info->unusedmin_n;n--)
646 if(logmdct[n-1]>-floor1_rangedB &&
647 logmdct[n-1]+info->twofitatten>logmask[n-1])break;
649 /* quantize the relevant floor points and collect them into line fit
650 structures (one per minimal division) at the same time */
652 nonzero+=accumulate_fit(logmask,logmax,0,n,fits,n,info);
654 for(i=0;i<posts-1;i++)
655 nonzero+=accumulate_fit(logmask,logmax,look->sorted_index[i],
656 look->sorted_index[i+1],fits+i,
661 /* start by fitting the implicit base case.... */
664 int mse=fit_line(fits,posts-1,&y0,&y1);
666 /* Only a single nonzero point */
669 fit_line(fits,posts-1,&y0,&y1);
680 /* Non degenerate case */
681 /* start progressive splitting. This is a greedy, non-optimal
682 algorithm, but simple and close enough to the best
684 for(i=2;i<posts;i++){
685 int sortpos=look->reverse_index[i];
686 int ln=loneighbor[sortpos];
687 int hn=hineighbor[sortpos];
689 /* eliminate repeat searches of a particular range with a memo */
691 /* haven't performed this error search yet */
692 int lsortpos=look->reverse_index[ln];
693 int hsortpos=look->reverse_index[hn];
696 /* if this is an empty segment, its endpoints don't matter.
698 for(j=lsortpos;j<hsortpos;j++)
701 /* empty segment; important to note that this does not
702 break 0/n post case */
711 /* A note: we want to bound/minimize *local*, not global, error */
712 int lx=info->postlist[ln];
713 int hx=info->postlist[hn];
714 int ly=post_Y(fit_valueA,fit_valueB,ln);
715 int hy=post_Y(fit_valueA,fit_valueB,hn);
717 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
718 /* outside error bounds/begin search area. Split it. */
723 int lmse=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
724 int hmse=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
726 /* the boundary/sparsity cases are the hard part. They
727 don't happen often given that we use the full mask
728 curve (weighted) now, but when they do happen they
729 can go boom. Pay them detailed attention */
730 /* cases for a segment:
731 >=0) normal fit (>=2 unique points)
733 one point on x1; <-- disallowed by fit_line
734 -2) one point in between x0 and x1
739 /* no points in the low segment */
742 ly0=fits[lsortpos].edgey0;
750 /* no points in the hi segment */
753 hy0=fits[sortpos].edgey0;
757 /* store new edge values */
759 if(ln==0 && ly0>=0)fit_valueA[ln]=ly0;
763 if(hn==1 && hy1>=0)fit_valueB[hn]=hy1;
765 if(ly0<0 && fit_valueA[ln]<0)
767 if(hy1<0 && fit_valueB[hn]<0)
770 if(ly1>=0 || hy0>=0){
771 /* store new neighbor values */
772 for(j=sortpos-1;j>=0;j--)
773 if(hineighbor[j]==hn)
777 for(j=sortpos+1;j<posts;j++)
778 if(loneighbor[j]==ln)
783 /* store flag (set) */
792 /* quantize values to multiplier spec */
794 case 1: /* 1024 -> 256 */
797 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>2;
799 case 2: /* 1024 -> 128 */
802 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>3;
804 case 3: /* 1024 -> 86 */
807 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)/12;
809 case 4: /* 1024 -> 64 */
812 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>4;
816 /* find prediction values for each post and subtract them */
817 for(i=2;i<posts;i++){
818 int sp=look->reverse_index[i];
819 int ln=look->loneighbor[i-2];
820 int hn=look->hineighbor[i-2];
821 int x0=info->postlist[ln];
822 int x1=info->postlist[hn];
823 int y0=fit_valueA[ln];
824 int y1=fit_valueA[hn];
826 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
829 int headroom=(look->quant_q-predicted<predicted?
830 look->quant_q-predicted:predicted);
832 int val=fit_valueA[i]-predicted;
834 /* at this point the 'deviation' value is in the range +/- max
835 range, but the real, unique range can always be mapped to
836 only [0-maxrange). So we want to wrap the deviation into
837 this limited range, but do it in the way that least screws
838 an essentially gaussian probability distribution. */
853 /* unroll the neighbor arrays */
854 for(j=sp+1;j<posts;j++)
856 loneighbor[j]=loneighbor[sp];
861 hineighbor[j]=hineighbor[sp];
866 fit_valueA[i]=predicted;
870 fit_valueA[i]|=0x8000;
872 fit_valueA[look->loneighbor[i-2]]&=0x7fff;
873 fit_valueA[look->hineighbor[i-2]]&=0x7fff;
877 /* we have everything we need. pack it out */
878 /* mark nontrivial floor */
879 oggpack_write(&vb->opb,1,1);
881 /* beginning/end post */
882 oggpack_write(&vb->opb,fit_valueA[0],ilog(look->quant_q-1));
883 oggpack_write(&vb->opb,fit_valueA[1],ilog(look->quant_q-1));
889 sprintf(buffer,"line%d_full.vqd",vb->mode);
890 of=fopen(buffer,"a");
892 fprintf(of,"%d\n",fit_valueB[j]);
898 /* partition by partition */
899 for(i=0,j=2;i<info->partitions;i++){
900 int class=info->partitionclass[i];
901 int cdim=info->class_dim[class];
902 int csubbits=info->class_subs[class];
903 int csub=1<<csubbits;
904 int bookas[8]={0,0,0,0,0,0,0,0};
908 /* generate the partition's first stage cascade value */
912 int booknum=info->class_subbook[class][k];
916 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
921 int val=fit_valueB[j+k];
927 cval|= bookas[k]<<cshift;
931 vorbis_book_encode(books+info->class_book[class],cval,&vb->opb);
937 sprintf(buffer,"line%d_class%d.vqd",vb->mode,class);
938 of=fopen(buffer,"a");
939 fprintf(of,"%d\n",cval);
945 /* write post values */
947 int book=info->class_subbook[class][bookas[k]];
949 vorbis_book_encode(books+book,
950 fit_valueB[j+k],&vb->opb);
956 sprintf(buffer,"line%d_%dsub%d.vqd",vb->mode,class,bookas[k]);
957 of=fopen(buffer,"a");
958 fprintf(of,"%d\n",fit_valueB[j+k]);
968 /* generate quantized floor equivalent to what we'd unpack in decode */
971 int ly=fit_valueA[0]*info->mult;
973 for(j=1;j<posts;j++){
974 int current=look->forward_index[j];
975 if(!(fit_valueA[current]&0x8000)){
976 int hy=(fit_valueA[current]&0x7fff)*info->mult;
977 hx=info->postlist[current];
979 render_line0(lx,hx,ly,hy,codedflr);
985 for(j=hx;j<look->n;j++)codedflr[j]=codedflr[j-1]; /* be certain */
987 /* use it to create residue vector. Eliminate residue elements
988 that were below the error training attenuation relative to
989 the original mask. This avoids portions of the floor fit
990 that were considered 'unused' in fitting from being used in
991 coding residue if the unfit values are significantly below
992 the original input mask */
994 if(logmdct[j]+info->twofitatten<logmask[j])
997 residue[j]=mdct[j]/codedflr[j];
998 for(j=n;j<look->n;j++)residue[j]=0.f;
1003 oggpack_write(&vb->opb,0,1);
1004 memset(codedflr,0,n*sizeof(float));
1005 memset(residue,0,n*sizeof(float));
1011 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
1012 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1013 vorbis_info_floor1 *info=look->vi;
1015 codec_setup_info *ci=vb->vd->vi->codec_setup;
1017 codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
1020 /* unpack wrapped/predicted values from stream */
1021 if(oggpack_read(&vb->opb,1)==1){
1022 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(int));
1024 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
1025 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
1027 /* partition by partition */
1028 /* partition by partition */
1029 for(i=0,j=2;i<info->partitions;i++){
1030 int class=info->partitionclass[i];
1031 int cdim=info->class_dim[class];
1032 int csubbits=info->class_subs[class];
1033 int csub=1<<csubbits;
1036 /* decode the partition's first stage cascade value */
1038 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
1040 if(cval==-1)goto eop;
1043 for(k=0;k<cdim;k++){
1044 int book=info->class_subbook[class][cval&(csub-1)];
1047 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1056 /* unwrap positive values and reconsitute via linear interpolation */
1057 for(i=2;i<look->posts;i++){
1058 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1059 info->postlist[look->hineighbor[i-2]],
1060 fit_value[look->loneighbor[i-2]],
1061 fit_value[look->hineighbor[i-2]],
1063 int hiroom=look->quant_q-predicted;
1064 int loroom=predicted;
1065 int room=(hiroom<loroom?hiroom:loroom)<<1;
1066 int val=fit_value[i];
1073 val = -1-(val-hiroom);
1083 fit_value[i]=val+predicted;
1084 fit_value[look->loneighbor[i-2]]&=0x7fff;
1085 fit_value[look->hineighbor[i-2]]&=0x7fff;
1088 fit_value[i]=predicted|0x8000;
1099 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1101 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1102 vorbis_info_floor1 *info=look->vi;
1104 codec_setup_info *ci=vb->vd->vi->codec_setup;
1105 int n=ci->blocksizes[vb->mode]/2;
1109 /* render the lines */
1110 int *fit_value=(int *)memo;
1113 int ly=fit_value[0]*info->mult;
1114 for(j=1;j<look->posts;j++){
1115 int current=look->forward_index[j];
1116 int hy=fit_value[current]&0x7fff;
1117 if(hy==fit_value[current]){
1120 hx=info->postlist[current];
1122 render_line(lx,hx,ly,hy,out);
1128 for(j=hx;j<n;j++)out[j]*=out[j-1]; /* be certain */
1131 memset(out,0,sizeof(float)*n);
1136 vorbis_func_floor floor1_exportbundle={
1137 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_copy_info,&floor1_free_info,
1138 &floor1_free_look,&floor1_forward,&floor1_inverse1,&floor1_inverse2