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-2002 *
9 * by the XIPHOPHORUS Company http://www.xiph.org/ *
11 ********************************************************************
13 function: floor backend 1 implementation
14 last mod: $Id: floor1.c,v 1.20 2002/01/22 08:06:06 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;
51 typedef struct lsfit_acc{
67 /***********************************************/
69 static vorbis_info_floor *floor1_copy_info (vorbis_info_floor *i){
70 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
71 vorbis_info_floor1 *ret=_ogg_malloc(sizeof(*ret));
72 memcpy(ret,info,sizeof(*ret));
76 static void floor1_free_info(vorbis_info_floor *i){
77 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
79 memset(info,0,sizeof(*info));
84 static void floor1_free_look(vorbis_look_floor *i){
85 vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
87 /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n",
88 (float)look->phrasebits/look->frames,
89 (float)look->postbits/look->frames,
90 (float)(look->postbits+look->phrasebits)/look->frames);*/
92 memset(look,0,sizeof(*look));
97 static int ilog(unsigned int v){
106 static int ilog2(unsigned int v){
115 static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
116 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
120 int maxposit=info->postlist[1];
123 /* save out partitions */
124 oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */
125 for(j=0;j<info->partitions;j++){
126 oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */
127 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
130 /* save out partition classes */
131 for(j=0;j<maxclass+1;j++){
132 oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
133 oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
134 if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
135 for(k=0;k<(1<<info->class_subs[j]);k++)
136 oggpack_write(opb,info->class_subbook[j][k]+1,8);
139 /* save out the post list */
140 oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */
141 oggpack_write(opb,ilog2(maxposit),4);
142 rangebits=ilog2(maxposit);
144 for(j=0,k=0;j<info->partitions;j++){
145 count+=info->class_dim[info->partitionclass[j]];
147 oggpack_write(opb,info->postlist[k+2],rangebits);
152 static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
153 codec_setup_info *ci=vi->codec_setup;
154 int j,k,count=0,maxclass=-1,rangebits;
156 vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info));
157 /* read partitions */
158 info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
159 for(j=0;j<info->partitions;j++){
160 info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
161 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
164 /* read partition classes */
165 for(j=0;j<maxclass+1;j++){
166 info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
167 info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
168 if(info->class_subs[j]<0)
170 if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
171 if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
173 for(k=0;k<(1<<info->class_subs[j]);k++){
174 info->class_subbook[j][k]=oggpack_read(opb,8)-1;
175 if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
180 /* read the post list */
181 info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
182 rangebits=oggpack_read(opb,4);
184 for(j=0,k=0;j<info->partitions;j++){
185 count+=info->class_dim[info->partitionclass[j]];
187 int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
188 if(t<0 || t>=(1<<rangebits))
193 info->postlist[1]=1<<rangebits;
198 floor1_free_info(info);
202 static int icomp(const void *a,const void *b){
203 return(**(int **)a-**(int **)b);
206 static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,vorbis_info_mode *mi,
207 vorbis_info_floor *in){
209 int *sortpointer[VIF_POSIT+2];
210 vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
211 vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(*look));
215 look->n=info->postlist[1];
217 /* we drop each position value in-between already decoded values,
218 and use linear interpolation to predict each new value past the
219 edges. The positions are read in the order of the position
220 list... we precompute the bounding positions in the lookup. Of
221 course, the neighbors can change (if a position is declined), but
222 this is an initial mapping */
224 for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
228 /* also store a sorted position index */
229 for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
230 qsort(sortpointer,n,sizeof(*sortpointer),icomp);
232 /* points from sort order back to range number */
233 for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
234 /* points from range order to sorted position */
235 for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
236 /* we actually need the post values too */
237 for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
239 /* quantize values to multiplier spec */
241 case 1: /* 1024 -> 256 */
244 case 2: /* 1024 -> 128 */
247 case 3: /* 1024 -> 86 */
250 case 4: /* 1024 -> 64 */
255 /* discover our neighbors for decode where we don't use fit flags
256 (that would push the neighbors outward) */
262 int currentx=info->postlist[i+2];
264 int x=info->postlist[j];
265 if(x>lx && x<currentx){
269 if(x<hx && x>currentx){
274 look->loneighbor[i]=lo;
275 look->hineighbor[i]=hi;
281 static int render_point(int x0,int x1,int y0,int y1,int x){
282 y0&=0x7fff; /* mask off flag */
292 if(dy<0)return(y0-off);
297 static int vorbis_dBquant(const float *x){
298 int i= *x*7.3142857f+1023.5f;
299 if(i>1023)return(1023);
304 static float FLOOR_fromdB_LOOKUP[256]={
305 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
306 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
307 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
308 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
309 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
310 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
311 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
312 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
313 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
314 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
315 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
316 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
317 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
318 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
319 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
320 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
321 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
322 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
323 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
324 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
325 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
326 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
327 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
328 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
329 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
330 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
331 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
332 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
333 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
334 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
335 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
336 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
337 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
338 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
339 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
340 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
341 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
342 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
343 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
344 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
345 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
346 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
347 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
348 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
349 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
350 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
351 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
352 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
353 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
354 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
355 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
356 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
357 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
358 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
359 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
360 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
361 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
362 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
363 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
364 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
365 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
366 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
367 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
368 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
371 static void render_line(int x0,int x1,int y0,int y1,float *d){
376 int sy=(dy<0?base-1:base+1);
383 d[x]*=FLOOR_fromdB_LOOKUP[y];
392 d[x]*=FLOOR_fromdB_LOOKUP[y];
396 static void render_line0(int x0,int x1,int y0,int y1,float *d){
401 int sy=(dy<0?base-1:base+1);
408 d[x]=FLOOR_fromdB_LOOKUP[y];
417 d[x]=FLOOR_fromdB_LOOKUP[y];
421 /* the floor has already been filtered to only include relevant sections */
422 static int accumulate_fit(const float *flr,const float *mdct,
423 int x0, int x1,lsfit_acc *a,
424 int n,vorbis_info_floor1 *info){
426 int quantized=vorbis_dBquant(flr+x0);
428 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;
430 memset(a,0,sizeof(*a));
437 int quantized=vorbis_dBquant(flr+i);
439 if(mdct[i]+info->twofitatten>=flr[i]){
443 y2a += quantized*quantized;
450 y2b += quantized*quantized;
464 /* weight toward the actually used frequencies if we meet the threshhold */
467 if(nb<info->twofitminsize || na<info->twofitminused){
470 weight=nb*info->twofitweight/na;
474 a->x2a=x2a*weight+x2b;
475 a->y2a=y2a*weight+y2b;
476 a->xya=xya*weight+xyb;
480 if(nb>=info->unusedminsize)a->un++;
485 int quantized=vorbis_dBquant(flr+i);
491 /* returns < 0 on too few points to fit, >=0 (meansq error) on success */
492 static int fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
493 long x=0,y=0,x2=0,y2=0,xy=0,n=0,an=0,i;
495 long x1=a[fits-1].x1;
509 if(*y0>=0){ /* hint used to break degenerate cases */
519 if(*y1>=0){ /* hint used to break degenerate cases */
532 /* need 64 bit multiplies, which C doesn't give portably as int */
537 double denom=1./(an*fx2-fx*fx);
538 double a=(fy*fx2-fxy*fx)*denom;
539 double b=(an*fxy-fx*fy)*denom;
543 /* limit to our range! */
544 if(*y0>1023)*y0=1023;
545 if(*y1>1023)*y1=1023;
553 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
557 for(i=0;i<fits && y==0;i++)
563 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
565 vorbis_info_floor1 *info){
570 int sy=(dy<0?base-1:base+1);
574 int val=vorbis_dBquant(mask+x);
580 if(mdct[x]+info->twofitatten>=mask[x]){
581 if(y+info->maxover<val)return(1);
582 if(y-info->maxunder>val)return(1);
597 if(mdct[x]+info->twofitatten>=mask[x]){
598 val=vorbis_dBquant(mask+x);
600 if(y+info->maxover<val)return(1);
601 if(y-info->maxunder>val)return(1);
602 mse+=((y-val)*(y-val));
609 if(info->maxover*info->maxover/n>info->maxerr)return(0);
610 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
611 if(mse/n>info->maxerr)return(1);
616 static int post_Y(int *A,int *B,int pos){
622 return (A[pos]+B[pos])>>1;
625 static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
626 float *mdct, const float *logmdct, /* in */
627 const float *logmask, const float *logmax, /* in */
628 float *codedflr){ /* out */
631 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
632 vorbis_info_floor1 *info=look->vi;
634 long posts=look->posts;
636 lsfit_acc fits[VIF_POSIT+1];
637 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
638 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
639 int fit_flag[VIF_POSIT+2];
641 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
642 int hineighbor[VIF_POSIT+2];
643 int memo[VIF_POSIT+2];
644 codec_setup_info *ci=vb->vd->vi->codec_setup;
645 static_codebook **sbooks=ci->book_param;
646 codebook *books=NULL;
649 if(vb->vd->backend_state){
654 memset(fit_flag,0,sizeof(fit_flag));
655 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
656 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
657 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
659 /* Scan back from high edge to first 'used' frequency */
660 for(;n>info->unusedmin_n;n--)
661 if(logmdct[n-1]>-floor1_rangedB &&
662 logmdct[n-1]+info->twofitatten>logmask[n-1])break;
664 /* quantize the relevant floor points and collect them into line fit
665 structures (one per minimal division) at the same time */
667 nonzero+=accumulate_fit(logmask,logmax,0,n,fits,n,info);
669 for(i=0;i<posts-1;i++)
670 nonzero+=accumulate_fit(logmask,logmax,look->sorted_index[i],
671 look->sorted_index[i+1],fits+i,
676 /* start by fitting the implicit base case.... */
679 int mse=fit_line(fits,posts-1,&y0,&y1);
681 /* Only a single nonzero point */
684 fit_line(fits,posts-1,&y0,&y1);
695 /* Non degenerate case */
696 /* start progressive splitting. This is a greedy, non-optimal
697 algorithm, but simple and close enough to the best
699 for(i=2;i<posts;i++){
700 int sortpos=look->reverse_index[i];
701 int ln=loneighbor[sortpos];
702 int hn=hineighbor[sortpos];
704 /* eliminate repeat searches of a particular range with a memo */
706 /* haven't performed this error search yet */
707 int lsortpos=look->reverse_index[ln];
708 int hsortpos=look->reverse_index[hn];
711 /* if this is an empty segment, its endpoints don't matter.
713 for(j=lsortpos;j<hsortpos;j++)
716 /* empty segment; important to note that this does not
717 break 0/n post case */
726 /* A note: we want to bound/minimize *local*, not global, error */
727 int lx=info->postlist[ln];
728 int hx=info->postlist[hn];
729 int ly=post_Y(fit_valueA,fit_valueB,ln);
730 int hy=post_Y(fit_valueA,fit_valueB,hn);
732 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
733 /* outside error bounds/begin search area. Split it. */
738 int lmse=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
739 int hmse=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
741 /* the boundary/sparsity cases are the hard part. They
742 don't happen often given that we use the full mask
743 curve (weighted) now, but when they do happen they
744 can go boom. Pay them detailed attention */
745 /* cases for a segment:
746 >=0) normal fit (>=2 unique points)
748 one point on x1; <-- disallowed by fit_line
749 -2) one point in between x0 and x1
754 /* no points in the low segment */
757 ly0=fits[lsortpos].edgey0;
765 /* no points in the hi segment */
768 hy0=fits[sortpos].edgey0;
772 /* store new edge values */
774 if(ln==0 && ly0>=0)fit_valueA[ln]=ly0;
778 if(hn==1 && hy1>=0)fit_valueB[hn]=hy1;
780 if(ly0<0 && fit_valueA[ln]<0)
782 if(hy1<0 && fit_valueB[hn]<0)
785 if(ly1>=0 || hy0>=0){
786 /* store new neighbor values */
787 for(j=sortpos-1;j>=0;j--)
788 if(hineighbor[j]==hn)
792 for(j=sortpos+1;j<posts;j++)
793 if(loneighbor[j]==ln)
798 /* store flag (set) */
807 /* quantize values to multiplier spec */
809 case 1: /* 1024 -> 256 */
812 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>2;
814 case 2: /* 1024 -> 128 */
817 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>3;
819 case 3: /* 1024 -> 86 */
822 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)/12;
824 case 4: /* 1024 -> 64 */
827 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>4;
831 /* find prediction values for each post and subtract them */
832 for(i=2;i<posts;i++){
833 int sp=look->reverse_index[i];
834 int ln=look->loneighbor[i-2];
835 int hn=look->hineighbor[i-2];
836 int x0=info->postlist[ln];
837 int x1=info->postlist[hn];
838 int y0=fit_valueA[ln];
839 int y1=fit_valueA[hn];
841 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
844 int headroom=(look->quant_q-predicted<predicted?
845 look->quant_q-predicted:predicted);
847 int val=fit_valueA[i]-predicted;
849 /* at this point the 'deviation' value is in the range +/- max
850 range, but the real, unique range can always be mapped to
851 only [0-maxrange). So we want to wrap the deviation into
852 this limited range, but do it in the way that least screws
853 an essentially gaussian probability distribution. */
868 /* unroll the neighbor arrays */
869 for(j=sp+1;j<posts;j++)
871 loneighbor[j]=loneighbor[sp];
876 hineighbor[j]=hineighbor[sp];
881 fit_valueA[i]=predicted;
885 fit_valueA[i]|=0x8000;
887 fit_valueA[look->loneighbor[i-2]]&=0x7fff;
888 fit_valueA[look->hineighbor[i-2]]&=0x7fff;
892 /* we have everything we need. pack it out */
893 /* mark nontrivial floor */
895 oggpack_write(&vb->opb,1,1);
897 /* beginning/end post */
899 look->postbits+=ilog(look->quant_q-1)*2;
900 oggpack_write(&vb->opb,fit_valueA[0],ilog(look->quant_q-1));
901 oggpack_write(&vb->opb,fit_valueA[1],ilog(look->quant_q-1));
904 /* partition by partition */
905 for(i=0,j=2;i<info->partitions;i++){
906 int class=info->partitionclass[i];
907 int cdim=info->class_dim[class];
908 int csubbits=info->class_subs[class];
909 int csub=1<<csubbits;
910 int bookas[8]={0,0,0,0,0,0,0,0};
914 /* generate the partition's first stage cascade value */
918 int booknum=info->class_subbook[class][k];
922 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
927 int val=fit_valueB[j+k];
933 cval|= bookas[k]<<cshift;
938 vorbis_book_encode(books+info->class_book[class],cval,&vb->opb);
944 sprintf(buffer,"line_%dx%ld_class%d.vqd",
945 vb->pcmend/2,posts-2,class);
946 of=fopen(buffer,"a");
947 fprintf(of,"%d\n",cval);
953 /* write post values */
955 int book=info->class_subbook[class][bookas[k]];
957 /* hack to allow training with 'bad' books */
958 if(fit_valueB[j+k]<(books+book)->entries)
959 look->postbits+=vorbis_book_encode(books+book,
960 fit_valueB[j+k],&vb->opb);
962 fprintf(stderr,"+!");*/
968 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
969 vb->pcmend/2,posts-2,class,bookas[k]);
970 of=fopen(buffer,"a");
971 fprintf(of,"%d\n",fit_valueB[j+k]);
982 /* generate quantized floor equivalent to what we'd unpack in decode */
985 int ly=fit_valueA[0]*info->mult;
987 for(j=1;j<posts;j++){
988 int current=look->forward_index[j];
989 if(!(fit_valueA[current]&0x8000)){
990 int hy=(fit_valueA[current]&0x7fff)*info->mult;
991 hx=info->postlist[current];
993 render_line0(lx,hx,ly,hy,codedflr);
999 for(j=lx;j<vb->pcmend/2;j++)codedflr[j]=codedflr[j-1]; /* be certain */
1001 /* use it to create residue vector. Eliminate mdct elements
1002 that were below the error training attenuation relative to
1003 the original mask. This avoids portions of the floor fit
1004 that were considered 'unused' in fitting from being used in
1005 coding residue if the unfit values are significantly below
1006 the original input mask */
1009 if(logmdct[j]+info->twofitatten<logmask[j])
1011 for(j=n;j<vb->pcmend/2;j++)mdct[j]=0.f;
1016 if(writeflag)oggpack_write(&vb->opb,0,1);
1017 memset(codedflr,0,n*sizeof(*codedflr));
1018 memset(mdct,0,n*sizeof(*mdct));
1024 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
1025 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1026 vorbis_info_floor1 *info=look->vi;
1027 codec_setup_info *ci=vb->vd->vi->codec_setup;
1030 codebook *books=ci->fullbooks;
1032 /* unpack wrapped/predicted values from stream */
1033 if(oggpack_read(&vb->opb,1)==1){
1034 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
1036 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
1037 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
1039 /* partition by partition */
1040 /* partition by partition */
1041 for(i=0,j=2;i<info->partitions;i++){
1042 int class=info->partitionclass[i];
1043 int cdim=info->class_dim[class];
1044 int csubbits=info->class_subs[class];
1045 int csub=1<<csubbits;
1048 /* decode the partition's first stage cascade value */
1050 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
1052 if(cval==-1)goto eop;
1055 for(k=0;k<cdim;k++){
1056 int book=info->class_subbook[class][cval&(csub-1)];
1059 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1068 /* unwrap positive values and reconsitute via linear interpolation */
1069 for(i=2;i<look->posts;i++){
1070 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1071 info->postlist[look->hineighbor[i-2]],
1072 fit_value[look->loneighbor[i-2]],
1073 fit_value[look->hineighbor[i-2]],
1075 int hiroom=look->quant_q-predicted;
1076 int loroom=predicted;
1077 int room=(hiroom<loroom?hiroom:loroom)<<1;
1078 int val=fit_value[i];
1085 val = -1-(val-hiroom);
1095 fit_value[i]=val+predicted;
1096 fit_value[look->loneighbor[i-2]]&=0x7fff;
1097 fit_value[look->hineighbor[i-2]]&=0x7fff;
1100 fit_value[i]=predicted|0x8000;
1111 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1113 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1114 vorbis_info_floor1 *info=look->vi;
1116 codec_setup_info *ci=vb->vd->vi->codec_setup;
1117 int n=ci->blocksizes[vb->mode]/2;
1121 /* render the lines */
1122 int *fit_value=(int *)memo;
1125 int ly=fit_value[0]*info->mult;
1126 for(j=1;j<look->posts;j++){
1127 int current=look->forward_index[j];
1128 int hy=fit_value[current]&0x7fff;
1129 if(hy==fit_value[current]){
1132 hx=info->postlist[current];
1134 render_line(lx,hx,ly,hy,out);
1140 for(j=hx;j<n;j++)out[j]*=ly; /* be certain */
1143 memset(out,0,sizeof(*out)*n);
1148 vorbis_func_floor floor1_exportbundle={
1149 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_copy_info,&floor1_free_info,
1150 &floor1_free_look,&floor1_forward,&floor1_inverse1,&floor1_inverse2