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.9 2001/06/15 23:31: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 static void render_line0(int x0,int x1,int y0,int y1,float *d){
403 int sy=(dy<0?base-1:base+1);
410 d[x]=FLOOR_fromdB_LOOKUP[y];
419 d[x]=FLOOR_fromdB_LOOKUP[y];
423 /* the floor has already been filtered to only include relevant sections */
424 static int accumulate_fit(const float *flr,const float *mdct,
425 int x0, int x1,lsfit_acc *a,
426 int n,vorbis_info_floor1 *info){
428 int quantized=vorbis_dBquant(flr);
430 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;
432 memset(a,0,sizeof(lsfit_acc));
439 int quantized=vorbis_dBquant(flr+i);
441 if(mdct[i]+info->twofitatten>=flr[i]){
445 y2a += quantized*quantized;
452 y2b += quantized*quantized;
466 /* weight toward the actually used frequencies if we meet the threshhold */
469 if(nb<info->twofitminsize || na<info->twofitminused){
472 weight=nb*info->twofitweight/na;
476 a->x2a=x2a*weight+x2b;
477 a->y2a=y2a*weight+y2b;
478 a->xya=xya*weight+xyb;
482 if(nb>=info->unusedminsize)a->un++;
487 int quantized=vorbis_dBquant(flr+i);
493 /* returns < 0 on too few points to fit, >=0 (meansq error) on success */
494 static int fit_line(lsfit_acc *a,int fits,int *y0,int *y1){
495 long x=0,y=0,x2=0,y2=0,xy=0,n=0,an=0,i;
497 long x1=a[fits-1].x1;
511 if(*y0>=0){ /* hint used to break degenerate cases */
521 if(*y1>=0){ /* hint used to break degenerate cases */
534 /* need 64 bit multiplies, which C doesn't give portably as int */
539 double denom=1./(an*fx2-fx*fx);
540 double a=(fy*fx2-fxy*fx)*denom;
541 double b=(an*fxy-fx*fy)*denom;
545 /* limit to our range! */
546 if(*y0>1023)*y0=1023;
547 if(*y1>1023)*y1=1023;
555 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
559 for(i=0;i<fits && y==0;i++)
565 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
567 vorbis_info_floor1 *info){
572 int sy=(dy<0?base-1:base+1);
576 int val=vorbis_dBquant(mask+x);
582 if(mdct[x]+info->twofitatten>=mask[x]){
583 if(y+info->maxover<val)return(1);
584 if(y-info->maxunder>val)return(1);
599 if(mdct[x]+info->twofitatten>=mask[x]){
600 val=vorbis_dBquant(mask+x);
602 if(y+info->maxover<val)return(1);
603 if(y-info->maxunder>val)return(1);
604 mse+=((y-val)*(y-val));
611 if(info->maxover*info->maxover/n>info->maxerr)return(0);
612 if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
613 if(mse/n>info->maxerr)return(1);
618 static int post_Y(int *A,int *B,int pos){
623 return (A[pos]+B[pos])>>1;
626 static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
627 const float *mdct, const float *logmdct, /* in */
628 const float *logmask, const float *logmax, /* in */
629 float *residue, float *codedflr){ /* out */
632 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
633 vorbis_info_floor1 *info=look->vi;
635 long posts=look->posts;
637 lsfit_acc fits[VIF_POSIT+1];
638 int fit_valueA[VIF_POSIT+2]; /* index by range list position */
639 int fit_valueB[VIF_POSIT+2]; /* index by range list position */
640 int fit_flag[VIF_POSIT+2];
642 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
643 int hineighbor[VIF_POSIT+2];
644 int memo[VIF_POSIT+2];
645 codec_setup_info *ci=vb->vd->vi->codec_setup;
646 static_codebook **sbooks=ci->book_param;
647 codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
650 memset(fit_flag,0,sizeof(fit_flag));
651 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
652 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
653 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
655 /* Scan back from high edge to first 'used' frequency */
656 for(;n>info->unusedmin_n;n--)
657 if(logmdct[n-1]>-floor1_rangedB &&
658 logmdct[n-1]+info->twofitatten>logmask[n-1])break;
660 /* quantize the relevant floor points and collect them into line fit
661 structures (one per minimal division) at the same time */
663 nonzero+=accumulate_fit(logmask,logmax,0,n,fits,n,info);
665 for(i=0;i<posts-1;i++)
666 nonzero+=accumulate_fit(logmask,logmax,look->sorted_index[i],
667 look->sorted_index[i+1],fits+i,
672 /* start by fitting the implicit base case.... */
675 int mse=fit_line(fits,posts-1,&y0,&y1);
677 /* Only a single nonzero point */
680 fit_line(fits,posts-1,&y0,&y1);
693 /* Non degenerate case */
694 /* start progressive splitting. This is a greedy, non-optimal
695 algorithm, but simple and close enough to the best
697 for(i=2;i<posts;i++){
698 int sortpos=look->reverse_index[i];
699 int ln=loneighbor[sortpos];
700 int hn=hineighbor[sortpos];
702 /* eliminate repeat searches of a particular range with a memo */
704 /* haven't performed this error search yet */
705 int lsortpos=look->reverse_index[ln];
706 int hsortpos=look->reverse_index[hn];
709 /* if this is an empty segment, its endpoints don't matter.
711 for(j=lsortpos;j<hsortpos;j++)
714 /* empty segment; important to note that this does not
715 break 0/n post case */
724 /* A note: we want to bound/minimize *local*, not global, error */
725 int lx=info->postlist[ln];
726 int hx=info->postlist[hn];
727 int ly=post_Y(fit_valueA,fit_valueB,ln);
728 int hy=post_Y(fit_valueA,fit_valueB,hn);
730 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
731 /* outside error bounds/begin search area. Split it. */
736 int lmse=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
737 int hmse=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
739 /* the boundary/sparsity cases are the hard part. They
740 don't happen often given that we use the full mask
741 curve (weighted) now, but when they do happen they
742 can go boom. Pay them detailed attention */
743 /* cases for a segment:
744 >=0) normal fit (>=2 unique points)
746 one point on x1; <-- disallowed by fit_line
747 -2) one point in between x0 and x1
752 /* no points in the low segment */
755 ly0=fits[lsortpos].edgey0;
763 /* no points in the hi segment */
766 hy0=fits[sortpos].edgey0;
770 /* store new edge values */
772 if(ln==0 && ly0>=0)fit_valueA[ln]=ly0;
776 if(hn==1 && hy1>=0)fit_valueB[hn]=hy1;
778 if(ly0<0 && fit_valueA[ln]<0)
780 if(hy1<0 && fit_valueB[hn]<0)
783 if(ly1>=0 || hy0>=0){
784 /* store new neighbor values */
785 for(j=sortpos-1;j>=0;j--)
786 if(hineighbor[j]==hn)
790 for(j=sortpos+1;j<posts;j++)
791 if(loneighbor[j]==ln)
796 /* store flag (set) */
805 /* quantize values to multiplier spec */
807 case 1: /* 1024 -> 256 */
810 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>2;
812 case 2: /* 1024 -> 128 */
815 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>3;
817 case 3: /* 1024 -> 86 */
820 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)/12;
822 case 4: /* 1024 -> 64 */
825 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>4;
829 /* find prediction values for each post and subtract them */
830 for(i=2;i<posts;i++){
831 int sp=look->reverse_index[i];
832 int ln=look->loneighbor[i-2];
833 int hn=look->hineighbor[i-2];
834 int x0=info->postlist[ln];
835 int x1=info->postlist[hn];
836 int y0=fit_valueA[ln];
837 int y1=fit_valueA[hn];
839 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
842 int headroom=(look->quant_q-predicted<predicted?
843 look->quant_q-predicted:predicted);
845 int val=fit_valueA[i]-predicted;
847 /* at this point the 'deviation' value is in the range +/- max
848 range, but the real, unique range can always be mapped to
849 only [0-maxrange). So we want to wrap the deviation into
850 this limited range, but do it in the way that least screws
851 an essentially gaussian probability distribution. */
866 /* unroll the neighbor arrays */
867 for(j=sp+1;j<posts;j++)
869 loneighbor[j]=loneighbor[sp];
874 hineighbor[j]=hineighbor[sp];
879 fit_valueA[i]=predicted;
883 fit_valueA[i]|=0x8000;
885 fit_valueA[look->loneighbor[i-2]]&=0x7fff;
886 fit_valueA[look->hineighbor[i-2]]&=0x7fff;
890 /* we have everything we need. pack it out */
891 /* mark nontrivial floor */
892 oggpack_write(&vb->opb,1,1);
894 /* beginning/end post */
895 look->postbits+=ilog(look->quant_q-1)*2;
896 oggpack_write(&vb->opb,fit_valueA[0],ilog(look->quant_q-1));
897 oggpack_write(&vb->opb,fit_valueA[1],ilog(look->quant_q-1));
903 sprintf(buffer,"line%d_full.vqd",vb->mode);
904 of=fopen(buffer,"a");
906 fprintf(of,"%d\n",fit_valueB[j]);
912 /* partition by partition */
913 for(i=0,j=2;i<info->partitions;i++){
914 int class=info->partitionclass[i];
915 int cdim=info->class_dim[class];
916 int csubbits=info->class_subs[class];
917 int csub=1<<csubbits;
918 int bookas[8]={0,0,0,0,0,0,0,0};
922 /* generate the partition's first stage cascade value */
926 int booknum=info->class_subbook[class][k];
930 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
935 int val=fit_valueB[j+k];
941 cval|= bookas[k]<<cshift;
945 look->classbits+=vorbis_book_encode(books+info->class_book[class],cval,&vb->opb);
951 sprintf(buffer,"line%d_class%d.vqd",vb->mode,class);
952 of=fopen(buffer,"a");
953 fprintf(of,"%d\n",cval);
959 /* write post values */
961 int book=info->class_subbook[class][bookas[k]];
963 look->subbits+=vorbis_book_encode(books+book,
964 fit_valueB[j+k],&vb->opb);
970 sprintf(buffer,"line%d_%dsub%d.vqd",vb->mode,class,bookas[k]);
971 of=fopen(buffer,"a");
972 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=hx;j<look->n;j++)codedflr[j]=codedflr[j-1]; /* be certain */
1001 /* use it to create residue vector. Eliminate residue 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 */
1008 if(logmdct[j]+info->twofitatten<logmask[j])
1011 residue[j]=mdct[j]/codedflr[j];
1012 for(j=n;j<look->n;j++)residue[j]=0.f;
1017 oggpack_write(&vb->opb,0,1);
1018 memset(codedflr,0,n*sizeof(float));
1019 memset(residue,0,n*sizeof(float));
1025 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
1026 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1027 vorbis_info_floor1 *info=look->vi;
1029 codec_setup_info *ci=vb->vd->vi->codec_setup;
1031 codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
1034 /* unpack wrapped/predicted values from stream */
1035 if(oggpack_read(&vb->opb,1)==1){
1036 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(int));
1038 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
1039 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
1041 /* partition by partition */
1042 /* partition by partition */
1043 for(i=0,j=2;i<info->partitions;i++){
1044 int class=info->partitionclass[i];
1045 int cdim=info->class_dim[class];
1046 int csubbits=info->class_subs[class];
1047 int csub=1<<csubbits;
1050 /* decode the partition's first stage cascade value */
1052 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
1054 if(cval==-1)goto eop;
1057 for(k=0;k<cdim;k++){
1058 int book=info->class_subbook[class][cval&(csub-1)];
1061 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1070 /* unwrap positive values and reconsitute via linear interpolation */
1071 for(i=2;i<look->posts;i++){
1072 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1073 info->postlist[look->hineighbor[i-2]],
1074 fit_value[look->loneighbor[i-2]],
1075 fit_value[look->hineighbor[i-2]],
1077 int hiroom=look->quant_q-predicted;
1078 int loroom=predicted;
1079 int room=(hiroom<loroom?hiroom:loroom)<<1;
1080 int val=fit_value[i];
1087 val = -1-(val-hiroom);
1097 fit_value[i]=val+predicted;
1098 fit_value[look->loneighbor[i-2]]&=0x7fff;
1099 fit_value[look->hineighbor[i-2]]&=0x7fff;
1102 fit_value[i]=predicted|0x8000;
1113 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1115 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1116 vorbis_info_floor1 *info=look->vi;
1118 codec_setup_info *ci=vb->vd->vi->codec_setup;
1119 int n=ci->blocksizes[vb->mode]/2;
1123 /* render the lines */
1124 int *fit_value=(int *)memo;
1127 int ly=fit_value[0]*info->mult;
1128 for(j=1;j<look->posts;j++){
1129 int current=look->forward_index[j];
1130 int hy=fit_value[current]&0x7fff;
1131 if(hy==fit_value[current]){
1134 hx=info->postlist[current];
1136 render_line(lx,hx,ly,hy,out);
1142 for(j=hx;j<n;j++)out[j]*=out[j-1]; /* be certain */
1145 memset(out,0,sizeof(float)*n);
1150 vorbis_func_floor floor1_exportbundle={
1151 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_copy_info,&floor1_free_info,
1152 &floor1_free_look,&floor1_forward,&floor1_inverse1,&floor1_inverse2