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