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.19 2001/12/19 23:13:33 segher 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){
650 books=((backend_lookup_state *)(vb->vd->backend_state))->
655 memset(fit_flag,0,sizeof(fit_flag));
656 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
657 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
658 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */
660 /* Scan back from high edge to first 'used' frequency */
661 for(;n>info->unusedmin_n;n--)
662 if(logmdct[n-1]>-floor1_rangedB &&
663 logmdct[n-1]+info->twofitatten>logmask[n-1])break;
665 /* quantize the relevant floor points and collect them into line fit
666 structures (one per minimal division) at the same time */
668 nonzero+=accumulate_fit(logmask,logmax,0,n,fits,n,info);
670 for(i=0;i<posts-1;i++)
671 nonzero+=accumulate_fit(logmask,logmax,look->sorted_index[i],
672 look->sorted_index[i+1],fits+i,
677 /* start by fitting the implicit base case.... */
680 int mse=fit_line(fits,posts-1,&y0,&y1);
682 /* Only a single nonzero point */
685 fit_line(fits,posts-1,&y0,&y1);
696 /* Non degenerate case */
697 /* start progressive splitting. This is a greedy, non-optimal
698 algorithm, but simple and close enough to the best
700 for(i=2;i<posts;i++){
701 int sortpos=look->reverse_index[i];
702 int ln=loneighbor[sortpos];
703 int hn=hineighbor[sortpos];
705 /* eliminate repeat searches of a particular range with a memo */
707 /* haven't performed this error search yet */
708 int lsortpos=look->reverse_index[ln];
709 int hsortpos=look->reverse_index[hn];
712 /* if this is an empty segment, its endpoints don't matter.
714 for(j=lsortpos;j<hsortpos;j++)
717 /* empty segment; important to note that this does not
718 break 0/n post case */
727 /* A note: we want to bound/minimize *local*, not global, error */
728 int lx=info->postlist[ln];
729 int hx=info->postlist[hn];
730 int ly=post_Y(fit_valueA,fit_valueB,ln);
731 int hy=post_Y(fit_valueA,fit_valueB,hn);
733 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
734 /* outside error bounds/begin search area. Split it. */
739 int lmse=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
740 int hmse=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
742 /* the boundary/sparsity cases are the hard part. They
743 don't happen often given that we use the full mask
744 curve (weighted) now, but when they do happen they
745 can go boom. Pay them detailed attention */
746 /* cases for a segment:
747 >=0) normal fit (>=2 unique points)
749 one point on x1; <-- disallowed by fit_line
750 -2) one point in between x0 and x1
755 /* no points in the low segment */
758 ly0=fits[lsortpos].edgey0;
766 /* no points in the hi segment */
769 hy0=fits[sortpos].edgey0;
773 /* store new edge values */
775 if(ln==0 && ly0>=0)fit_valueA[ln]=ly0;
779 if(hn==1 && hy1>=0)fit_valueB[hn]=hy1;
781 if(ly0<0 && fit_valueA[ln]<0)
783 if(hy1<0 && fit_valueB[hn]<0)
786 if(ly1>=0 || hy0>=0){
787 /* store new neighbor values */
788 for(j=sortpos-1;j>=0;j--)
789 if(hineighbor[j]==hn)
793 for(j=sortpos+1;j<posts;j++)
794 if(loneighbor[j]==ln)
799 /* store flag (set) */
808 /* quantize values to multiplier spec */
810 case 1: /* 1024 -> 256 */
813 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>2;
815 case 2: /* 1024 -> 128 */
818 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>3;
820 case 3: /* 1024 -> 86 */
823 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)/12;
825 case 4: /* 1024 -> 64 */
828 fit_valueA[i]=post_Y(fit_valueA,fit_valueB,i)>>4;
832 /* find prediction values for each post and subtract them */
833 for(i=2;i<posts;i++){
834 int sp=look->reverse_index[i];
835 int ln=look->loneighbor[i-2];
836 int hn=look->hineighbor[i-2];
837 int x0=info->postlist[ln];
838 int x1=info->postlist[hn];
839 int y0=fit_valueA[ln];
840 int y1=fit_valueA[hn];
842 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
845 int headroom=(look->quant_q-predicted<predicted?
846 look->quant_q-predicted:predicted);
848 int val=fit_valueA[i]-predicted;
850 /* at this point the 'deviation' value is in the range +/- max
851 range, but the real, unique range can always be mapped to
852 only [0-maxrange). So we want to wrap the deviation into
853 this limited range, but do it in the way that least screws
854 an essentially gaussian probability distribution. */
869 /* unroll the neighbor arrays */
870 for(j=sp+1;j<posts;j++)
872 loneighbor[j]=loneighbor[sp];
877 hineighbor[j]=hineighbor[sp];
882 fit_valueA[i]=predicted;
886 fit_valueA[i]|=0x8000;
888 fit_valueA[look->loneighbor[i-2]]&=0x7fff;
889 fit_valueA[look->hineighbor[i-2]]&=0x7fff;
893 /* we have everything we need. pack it out */
894 /* mark nontrivial floor */
896 oggpack_write(&vb->opb,1,1);
898 /* beginning/end post */
900 look->postbits+=ilog(look->quant_q-1)*2;
901 oggpack_write(&vb->opb,fit_valueA[0],ilog(look->quant_q-1));
902 oggpack_write(&vb->opb,fit_valueA[1],ilog(look->quant_q-1));
905 /* partition by partition */
906 for(i=0,j=2;i<info->partitions;i++){
907 int class=info->partitionclass[i];
908 int cdim=info->class_dim[class];
909 int csubbits=info->class_subs[class];
910 int csub=1<<csubbits;
911 int bookas[8]={0,0,0,0,0,0,0,0};
915 /* generate the partition's first stage cascade value */
919 int booknum=info->class_subbook[class][k];
923 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
928 int val=fit_valueB[j+k];
934 cval|= bookas[k]<<cshift;
939 vorbis_book_encode(books+info->class_book[class],cval,&vb->opb);
945 sprintf(buffer,"line_%dx%ld_class%d.vqd",
946 vb->pcmend/2,posts-2,class);
947 of=fopen(buffer,"a");
948 fprintf(of,"%d\n",cval);
954 /* write post values */
956 int book=info->class_subbook[class][bookas[k]];
958 /* hack to allow training with 'bad' books */
959 if(fit_valueB[j+k]<(books+book)->entries)
960 look->postbits+=vorbis_book_encode(books+book,
961 fit_valueB[j+k],&vb->opb);
963 fprintf(stderr,"+!");*/
969 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
970 vb->pcmend/2,posts-2,class,bookas[k]);
971 of=fopen(buffer,"a");
972 fprintf(of,"%d\n",fit_valueB[j+k]);
983 /* generate quantized floor equivalent to what we'd unpack in decode */
986 int ly=fit_valueA[0]*info->mult;
988 for(j=1;j<posts;j++){
989 int current=look->forward_index[j];
990 if(!(fit_valueA[current]&0x8000)){
991 int hy=(fit_valueA[current]&0x7fff)*info->mult;
992 hx=info->postlist[current];
994 render_line0(lx,hx,ly,hy,codedflr);
1000 for(j=lx;j<vb->pcmend/2;j++)codedflr[j]=codedflr[j-1]; /* be certain */
1002 /* use it to create residue vector. Eliminate mdct elements
1003 that were below the error training attenuation relative to
1004 the original mask. This avoids portions of the floor fit
1005 that were considered 'unused' in fitting from being used in
1006 coding residue if the unfit values are significantly below
1007 the original input mask */
1010 if(logmdct[j]+info->twofitatten<logmask[j])
1012 for(j=n;j<vb->pcmend/2;j++)mdct[j]=0.f;
1017 if(writeflag)oggpack_write(&vb->opb,0,1);
1018 memset(codedflr,0,n*sizeof(*codedflr));
1019 memset(mdct,0,n*sizeof(*mdct));
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;
1030 codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
1033 /* unpack wrapped/predicted values from stream */
1034 if(oggpack_read(&vb->opb,1)==1){
1035 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
1037 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
1038 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
1040 /* partition by partition */
1041 /* partition by partition */
1042 for(i=0,j=2;i<info->partitions;i++){
1043 int class=info->partitionclass[i];
1044 int cdim=info->class_dim[class];
1045 int csubbits=info->class_subs[class];
1046 int csub=1<<csubbits;
1049 /* decode the partition's first stage cascade value */
1051 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
1053 if(cval==-1)goto eop;
1056 for(k=0;k<cdim;k++){
1057 int book=info->class_subbook[class][cval&(csub-1)];
1060 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1069 /* unwrap positive values and reconsitute via linear interpolation */
1070 for(i=2;i<look->posts;i++){
1071 int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1072 info->postlist[look->hineighbor[i-2]],
1073 fit_value[look->loneighbor[i-2]],
1074 fit_value[look->hineighbor[i-2]],
1076 int hiroom=look->quant_q-predicted;
1077 int loroom=predicted;
1078 int room=(hiroom<loroom?hiroom:loroom)<<1;
1079 int val=fit_value[i];
1086 val = -1-(val-hiroom);
1096 fit_value[i]=val+predicted;
1097 fit_value[look->loneighbor[i-2]]&=0x7fff;
1098 fit_value[look->hineighbor[i-2]]&=0x7fff;
1101 fit_value[i]=predicted|0x8000;
1112 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1114 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1115 vorbis_info_floor1 *info=look->vi;
1117 codec_setup_info *ci=vb->vd->vi->codec_setup;
1118 int n=ci->blocksizes[vb->mode]/2;
1122 /* render the lines */
1123 int *fit_value=(int *)memo;
1126 int ly=fit_value[0]*info->mult;
1127 for(j=1;j<look->posts;j++){
1128 int current=look->forward_index[j];
1129 int hy=fit_value[current]&0x7fff;
1130 if(hy==fit_value[current]){
1133 hx=info->postlist[current];
1135 render_line(lx,hx,ly,hy,out);
1141 for(j=hx;j<n;j++)out[j]*=ly; /* be certain */
1144 memset(out,0,sizeof(*out)*n);
1149 vorbis_func_floor floor1_exportbundle={
1150 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_copy_info,&floor1_free_info,
1151 &floor1_free_look,&floor1_forward,&floor1_inverse1,&floor1_inverse2