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-2009 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: floor backend 1 implementation
14 last mod: $Id: floor1.c 16227 2009-07-08 06:58:46Z xiphmont $
16 ********************************************************************/
22 #include "vorbis/codec.h"
23 #include "codec_internal.h"
31 #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
33 typedef struct lsfit_acc
{
45 /***********************************************/
47 static void floor1_free_info(vorbis_info_floor
*i
){
48 vorbis_info_floor1
*info
=(vorbis_info_floor1
*)i
;
50 memset(info
,0,sizeof(*info
));
55 static void floor1_free_look(vorbis_look_floor
*i
){
56 vorbis_look_floor1
*look
=(vorbis_look_floor1
*)i
;
58 /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n",
59 (float)look->phrasebits/look->frames,
60 (float)look->postbits/look->frames,
61 (float)(look->postbits+look->phrasebits)/look->frames);*/
63 memset(look
,0,sizeof(*look
));
68 static int ilog(unsigned int v
){
77 static int ilog2(unsigned int v
){
87 static void floor1_pack (vorbis_info_floor
*i
,oggpack_buffer
*opb
){
88 vorbis_info_floor1
*info
=(vorbis_info_floor1
*)i
;
92 int maxposit
=info
->postlist
[1];
95 /* save out partitions */
96 oggpack_write(opb
,info
->partitions
,5); /* only 0 to 31 legal */
97 for(j
=0;j
<info
->partitions
;j
++){
98 oggpack_write(opb
,info
->partitionclass
[j
],4); /* only 0 to 15 legal */
99 if(maxclass
<info
->partitionclass
[j
])maxclass
=info
->partitionclass
[j
];
102 /* save out partition classes */
103 for(j
=0;j
<maxclass
+1;j
++){
104 oggpack_write(opb
,info
->class_dim
[j
]-1,3); /* 1 to 8 */
105 oggpack_write(opb
,info
->class_subs
[j
],2); /* 0 to 3 */
106 if(info
->class_subs
[j
])oggpack_write(opb
,info
->class_book
[j
],8);
107 for(k
=0;k
<(1<<info
->class_subs
[j
]);k
++)
108 oggpack_write(opb
,info
->class_subbook
[j
][k
]+1,8);
111 /* save out the post list */
112 oggpack_write(opb
,info
->mult
-1,2); /* only 1,2,3,4 legal now */
113 oggpack_write(opb
,ilog2(maxposit
),4);
114 rangebits
=ilog2(maxposit
);
116 for(j
=0,k
=0;j
<info
->partitions
;j
++){
117 count
+=info
->class_dim
[info
->partitionclass
[j
]];
119 oggpack_write(opb
,info
->postlist
[k
+2],rangebits
);
123 static int icomp(const void *a
,const void *b
){
124 return(**(int **)a
-**(int **)b
);
127 static vorbis_info_floor
*floor1_unpack (vorbis_info
*vi
,oggpack_buffer
*opb
){
128 codec_setup_info
*ci
=vi
->codec_setup
;
129 int j
,k
,count
=0,maxclass
=-1,rangebits
;
131 vorbis_info_floor1
*info
=_ogg_calloc(1,sizeof(*info
));
132 /* read partitions */
133 info
->partitions
=oggpack_read(opb
,5); /* only 0 to 31 legal */
134 for(j
=0;j
<info
->partitions
;j
++){
135 info
->partitionclass
[j
]=oggpack_read(opb
,4); /* only 0 to 15 legal */
136 if(info
->partitionclass
[j
]<0)goto err_out
;
137 if(maxclass
<info
->partitionclass
[j
])maxclass
=info
->partitionclass
[j
];
140 /* read partition classes */
141 for(j
=0;j
<maxclass
+1;j
++){
142 info
->class_dim
[j
]=oggpack_read(opb
,3)+1; /* 1 to 8 */
143 info
->class_subs
[j
]=oggpack_read(opb
,2); /* 0,1,2,3 bits */
144 if(info
->class_subs
[j
]<0)
146 if(info
->class_subs
[j
])info
->class_book
[j
]=oggpack_read(opb
,8);
147 if(info
->class_book
[j
]<0 || info
->class_book
[j
]>=ci
->books
)
149 for(k
=0;k
<(1<<info
->class_subs
[j
]);k
++){
150 info
->class_subbook
[j
][k
]=oggpack_read(opb
,8)-1;
151 if(info
->class_subbook
[j
][k
]<-1 || info
->class_subbook
[j
][k
]>=ci
->books
)
156 /* read the post list */
157 info
->mult
=oggpack_read(opb
,2)+1; /* only 1,2,3,4 legal now */
158 rangebits
=oggpack_read(opb
,4);
159 if(rangebits
<0)goto err_out
;
161 for(j
=0,k
=0;j
<info
->partitions
;j
++){
162 count
+=info
->class_dim
[info
->partitionclass
[j
]];
164 int t
=info
->postlist
[k
+2]=oggpack_read(opb
,rangebits
);
165 if(t
<0 || t
>=(1<<rangebits
))
170 info
->postlist
[1]=1<<rangebits
;
172 /* don't allow repeated values in post list as they'd result in
173 zero-length segments */
175 int *sortpointer
[VIF_POSIT
+2];
176 for(j
=0;j
<count
+2;j
++)sortpointer
[j
]=info
->postlist
+j
;
177 qsort(sortpointer
,count
+2,sizeof(*sortpointer
),icomp
);
179 for(j
=1;j
<count
+2;j
++)
180 if(*sortpointer
[j
-1]==*sortpointer
[j
])goto err_out
;
186 floor1_free_info(info
);
190 static vorbis_look_floor
*floor1_look(vorbis_dsp_state
*vd
,
191 vorbis_info_floor
*in
){
193 int *sortpointer
[VIF_POSIT
+2];
194 vorbis_info_floor1
*info
=(vorbis_info_floor1
*)in
;
195 vorbis_look_floor1
*look
=_ogg_calloc(1,sizeof(*look
));
199 look
->n
=info
->postlist
[1];
201 /* we drop each position value in-between already decoded values,
202 and use linear interpolation to predict each new value past the
203 edges. The positions are read in the order of the position
204 list... we precompute the bounding positions in the lookup. Of
205 course, the neighbors can change (if a position is declined), but
206 this is an initial mapping */
208 for(i
=0;i
<info
->partitions
;i
++)n
+=info
->class_dim
[info
->partitionclass
[i
]];
212 /* also store a sorted position index */
213 for(i
=0;i
<n
;i
++)sortpointer
[i
]=info
->postlist
+i
;
214 qsort(sortpointer
,n
,sizeof(*sortpointer
),icomp
);
216 /* points from sort order back to range number */
217 for(i
=0;i
<n
;i
++)look
->forward_index
[i
]=sortpointer
[i
]-info
->postlist
;
218 /* points from range order to sorted position */
219 for(i
=0;i
<n
;i
++)look
->reverse_index
[look
->forward_index
[i
]]=i
;
220 /* we actually need the post values too */
221 for(i
=0;i
<n
;i
++)look
->sorted_index
[i
]=info
->postlist
[look
->forward_index
[i
]];
223 /* quantize values to multiplier spec */
225 case 1: /* 1024 -> 256 */
228 case 2: /* 1024 -> 128 */
231 case 3: /* 1024 -> 86 */
234 case 4: /* 1024 -> 64 */
239 /* discover our neighbors for decode where we don't use fit flags
240 (that would push the neighbors outward) */
246 int currentx
=info
->postlist
[i
+2];
248 int x
=info
->postlist
[j
];
249 if(x
>lx
&& x
<currentx
){
253 if(x
<hx
&& x
>currentx
){
258 look
->loneighbor
[i
]=lo
;
259 look
->hineighbor
[i
]=hi
;
265 static int render_point(int x0
,int x1
,int y0
,int y1
,int x
){
266 y0
&=0x7fff; /* mask off flag */
276 if(dy
<0)return(y0
-off
);
281 static int vorbis_dBquant(const float *x
){
282 int i
= *x
*7.3142857f
+1023.5f
;
283 if(i
>1023)return(1023);
288 static const float FLOOR1_fromdB_LOOKUP
[256]={
289 1.0649863e-07F
, 1.1341951e-07F
, 1.2079015e-07F
, 1.2863978e-07F
,
290 1.3699951e-07F
, 1.4590251e-07F
, 1.5538408e-07F
, 1.6548181e-07F
,
291 1.7623575e-07F
, 1.8768855e-07F
, 1.9988561e-07F
, 2.128753e-07F
,
292 2.2670913e-07F
, 2.4144197e-07F
, 2.5713223e-07F
, 2.7384213e-07F
,
293 2.9163793e-07F
, 3.1059021e-07F
, 3.3077411e-07F
, 3.5226968e-07F
,
294 3.7516214e-07F
, 3.9954229e-07F
, 4.2550680e-07F
, 4.5315863e-07F
,
295 4.8260743e-07F
, 5.1396998e-07F
, 5.4737065e-07F
, 5.8294187e-07F
,
296 6.2082472e-07F
, 6.6116941e-07F
, 7.0413592e-07F
, 7.4989464e-07F
,
297 7.9862701e-07F
, 8.5052630e-07F
, 9.0579828e-07F
, 9.6466216e-07F
,
298 1.0273513e-06F
, 1.0941144e-06F
, 1.1652161e-06F
, 1.2409384e-06F
,
299 1.3215816e-06F
, 1.4074654e-06F
, 1.4989305e-06F
, 1.5963394e-06F
,
300 1.7000785e-06F
, 1.8105592e-06F
, 1.9282195e-06F
, 2.0535261e-06F
,
301 2.1869758e-06F
, 2.3290978e-06F
, 2.4804557e-06F
, 2.6416497e-06F
,
302 2.8133190e-06F
, 2.9961443e-06F
, 3.1908506e-06F
, 3.3982101e-06F
,
303 3.6190449e-06F
, 3.8542308e-06F
, 4.1047004e-06F
, 4.3714470e-06F
,
304 4.6555282e-06F
, 4.9580707e-06F
, 5.2802740e-06F
, 5.6234160e-06F
,
305 5.9888572e-06F
, 6.3780469e-06F
, 6.7925283e-06F
, 7.2339451e-06F
,
306 7.7040476e-06F
, 8.2047000e-06F
, 8.7378876e-06F
, 9.3057248e-06F
,
307 9.9104632e-06F
, 1.0554501e-05F
, 1.1240392e-05F
, 1.1970856e-05F
,
308 1.2748789e-05F
, 1.3577278e-05F
, 1.4459606e-05F
, 1.5399272e-05F
,
309 1.6400004e-05F
, 1.7465768e-05F
, 1.8600792e-05F
, 1.9809576e-05F
,
310 2.1096914e-05F
, 2.2467911e-05F
, 2.3928002e-05F
, 2.5482978e-05F
,
311 2.7139006e-05F
, 2.8902651e-05F
, 3.0780908e-05F
, 3.2781225e-05F
,
312 3.4911534e-05F
, 3.7180282e-05F
, 3.9596466e-05F
, 4.2169667e-05F
,
313 4.4910090e-05F
, 4.7828601e-05F
, 5.0936773e-05F
, 5.4246931e-05F
,
314 5.7772202e-05F
, 6.1526565e-05F
, 6.5524908e-05F
, 6.9783085e-05F
,
315 7.4317983e-05F
, 7.9147585e-05F
, 8.4291040e-05F
, 8.9768747e-05F
,
316 9.5602426e-05F
, 0.00010181521F
, 0.00010843174F
, 0.00011547824F
,
317 0.00012298267F
, 0.00013097477F
, 0.00013948625F
, 0.00014855085F
,
318 0.00015820453F
, 0.00016848555F
, 0.00017943469F
, 0.00019109536F
,
319 0.00020351382F
, 0.00021673929F
, 0.00023082423F
, 0.00024582449F
,
320 0.00026179955F
, 0.00027881276F
, 0.00029693158F
, 0.00031622787F
,
321 0.00033677814F
, 0.00035866388F
, 0.00038197188F
, 0.00040679456F
,
322 0.00043323036F
, 0.00046138411F
, 0.00049136745F
, 0.00052329927F
,
323 0.00055730621F
, 0.00059352311F
, 0.00063209358F
, 0.00067317058F
,
324 0.00071691700F
, 0.00076350630F
, 0.00081312324F
, 0.00086596457F
,
325 0.00092223983F
, 0.00098217216F
, 0.0010459992F
, 0.0011139742F
,
326 0.0011863665F
, 0.0012634633F
, 0.0013455702F
, 0.0014330129F
,
327 0.0015261382F
, 0.0016253153F
, 0.0017309374F
, 0.0018434235F
,
328 0.0019632195F
, 0.0020908006F
, 0.0022266726F
, 0.0023713743F
,
329 0.0025254795F
, 0.0026895994F
, 0.0028643847F
, 0.0030505286F
,
330 0.0032487691F
, 0.0034598925F
, 0.0036847358F
, 0.0039241906F
,
331 0.0041792066F
, 0.0044507950F
, 0.0047400328F
, 0.0050480668F
,
332 0.0053761186F
, 0.0057254891F
, 0.0060975636F
, 0.0064938176F
,
333 0.0069158225F
, 0.0073652516F
, 0.0078438871F
, 0.0083536271F
,
334 0.0088964928F
, 0.009474637F
, 0.010090352F
, 0.010746080F
,
335 0.011444421F
, 0.012188144F
, 0.012980198F
, 0.013823725F
,
336 0.014722068F
, 0.015678791F
, 0.016697687F
, 0.017782797F
,
337 0.018938423F
, 0.020169149F
, 0.021479854F
, 0.022875735F
,
338 0.024362330F
, 0.025945531F
, 0.027631618F
, 0.029427276F
,
339 0.031339626F
, 0.033376252F
, 0.035545228F
, 0.037855157F
,
340 0.040315199F
, 0.042935108F
, 0.045725273F
, 0.048696758F
,
341 0.051861348F
, 0.055231591F
, 0.058820850F
, 0.062643361F
,
342 0.066714279F
, 0.071049749F
, 0.075666962F
, 0.080584227F
,
343 0.085821044F
, 0.091398179F
, 0.097337747F
, 0.10366330F
,
344 0.11039993F
, 0.11757434F
, 0.12521498F
, 0.13335215F
,
345 0.14201813F
, 0.15124727F
, 0.16107617F
, 0.17154380F
,
346 0.18269168F
, 0.19456402F
, 0.20720788F
, 0.22067342F
,
347 0.23501402F
, 0.25028656F
, 0.26655159F
, 0.28387361F
,
348 0.30232132F
, 0.32196786F
, 0.34289114F
, 0.36517414F
,
349 0.38890521F
, 0.41417847F
, 0.44109412F
, 0.46975890F
,
350 0.50028648F
, 0.53279791F
, 0.56742212F
, 0.60429640F
,
351 0.64356699F
, 0.68538959F
, 0.72993007F
, 0.77736504F
,
352 0.82788260F
, 0.88168307F
, 0.9389798F
, 1.F
,
355 static void render_line(int n
, int x0
,int x1
,int y0
,int y1
,float *d
){
360 int sy
=(dy
<0?base
-1:base
+1);
370 d
[x
]*=FLOOR1_fromdB_LOOKUP
[y
];
380 d
[x
]*=FLOOR1_fromdB_LOOKUP
[y
];
384 static void render_line0(int x0
,int x1
,int y0
,int y1
,int *d
){
389 int sy
=(dy
<0?base
-1:base
+1);
409 /* the floor has already been filtered to only include relevant sections */
410 static int accumulate_fit(const float *flr
,const float *mdct
,
411 int x0
, int x1
,lsfit_acc
*a
,
412 int n
,vorbis_info_floor1
*info
){
415 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;
417 memset(a
,0,sizeof(*a
));
423 int quantized
=vorbis_dBquant(flr
+i
);
425 if(mdct
[i
]+info
->twofitatten
>=flr
[i
]){
429 y2a
+= quantized
*quantized
;
436 y2b
+= quantized
*quantized
;
450 /* weight toward the actually used frequencies if we meet the threshhold */
452 int weight
=nb
*info
->twofitweight
/(na
+1);
456 a
->x2a
=x2a
*weight
+x2b
;
457 a
->y2a
=y2a
*weight
+y2b
;
458 a
->xya
=xya
*weight
+xyb
;
465 static int fit_line(lsfit_acc
*a
,int fits
,int *y0
,int *y1
){
466 long x
=0,y
=0,x2
=0,y2
=0,xy
=0,an
=0,i
;
468 long x1
=a
[fits
-1].x1
;
498 /* need 64 bit multiplies, which C doesn't give portably as int */
501 double denom
=(an
*fx2
-fx
*fx
);
507 double a
=(fy
*fx2
-fxy
*fx
)/denom
;
508 double b
=(an
*fxy
-fx
*fy
)/denom
;
512 /* limit to our range! */
513 if(*y0
>1023)*y0
=1023;
514 if(*y1
>1023)*y1
=1023;
527 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
531 for(i=0;i<fits && y==0;i++)
537 static int inspect_error(int x0
,int x1
,int y0
,int y1
,const float *mask
,
539 vorbis_info_floor1
*info
){
544 int sy
=(dy
<0?base
-1:base
+1);
548 int val
=vorbis_dBquant(mask
+x
);
557 if(mdct
[x
]+info
->twofitatten
>=mask
[x
]){
558 if(y
+info
->maxover
<val
)return(1);
559 if(y
-info
->maxunder
>val
)return(1);
571 val
=vorbis_dBquant(mask
+x
);
572 mse
+=((y
-val
)*(y
-val
));
574 if(mdct
[x
]+info
->twofitatten
>=mask
[x
]){
576 if(y
+info
->maxover
<val
)return(1);
577 if(y
-info
->maxunder
>val
)return(1);
582 if(info
->maxover
*info
->maxover
/n
>info
->maxerr
)return(0);
583 if(info
->maxunder
*info
->maxunder
/n
>info
->maxerr
)return(0);
584 if(mse
/n
>info
->maxerr
)return(1);
588 static int post_Y(int *A
,int *B
,int pos
){
594 return (A
[pos
]+B
[pos
])>>1;
597 int *floor1_fit(vorbis_block
*vb
,vorbis_look_floor1
*look
,
598 const float *logmdct
, /* in */
599 const float *logmask
){
601 vorbis_info_floor1
*info
=look
->vi
;
603 long posts
=look
->posts
;
605 lsfit_acc fits
[VIF_POSIT
+1];
606 int fit_valueA
[VIF_POSIT
+2]; /* index by range list position */
607 int fit_valueB
[VIF_POSIT
+2]; /* index by range list position */
609 int loneighbor
[VIF_POSIT
+2]; /* sorted index of range list position (+2) */
610 int hineighbor
[VIF_POSIT
+2];
612 int memo
[VIF_POSIT
+2];
614 for(i
=0;i
<posts
;i
++)fit_valueA
[i
]=-200; /* mark all unused */
615 for(i
=0;i
<posts
;i
++)fit_valueB
[i
]=-200; /* mark all unused */
616 for(i
=0;i
<posts
;i
++)loneighbor
[i
]=0; /* 0 for the implicit 0 post */
617 for(i
=0;i
<posts
;i
++)hineighbor
[i
]=1; /* 1 for the implicit post at n */
618 for(i
=0;i
<posts
;i
++)memo
[i
]=-1; /* no neighbor yet */
620 /* quantize the relevant floor points and collect them into line fit
621 structures (one per minimal division) at the same time */
623 nonzero
+=accumulate_fit(logmask
,logmdct
,0,n
,fits
,n
,info
);
625 for(i
=0;i
<posts
-1;i
++)
626 nonzero
+=accumulate_fit(logmask
,logmdct
,look
->sorted_index
[i
],
627 look
->sorted_index
[i
+1],fits
+i
,
632 /* start by fitting the implicit base case.... */
635 fit_line(fits
,posts
-1,&y0
,&y1
);
642 /* Non degenerate case */
643 /* start progressive splitting. This is a greedy, non-optimal
644 algorithm, but simple and close enough to the best
646 for(i
=2;i
<posts
;i
++){
647 int sortpos
=look
->reverse_index
[i
];
648 int ln
=loneighbor
[sortpos
];
649 int hn
=hineighbor
[sortpos
];
651 /* eliminate repeat searches of a particular range with a memo */
653 /* haven't performed this error search yet */
654 int lsortpos
=look
->reverse_index
[ln
];
655 int hsortpos
=look
->reverse_index
[hn
];
659 /* A note: we want to bound/minimize *local*, not global, error */
660 int lx
=info
->postlist
[ln
];
661 int hx
=info
->postlist
[hn
];
662 int ly
=post_Y(fit_valueA
,fit_valueB
,ln
);
663 int hy
=post_Y(fit_valueA
,fit_valueB
,hn
);
665 if(ly
==-1 || hy
==-1){
669 if(inspect_error(lx
,hx
,ly
,hy
,logmask
,logmdct
,info
)){
670 /* outside error bounds/begin search area. Split it. */
675 int ret0
=fit_line(fits
+lsortpos
,sortpos
-lsortpos
,&ly0
,&ly1
);
676 int ret1
=fit_line(fits
+sortpos
,hsortpos
-sortpos
,&hy0
,&hy1
);
691 /* store new edge values */
693 if(ln
==0)fit_valueA
[ln
]=ly0
;
697 if(hn
==1)fit_valueB
[hn
]=hy1
;
699 if(ly1
>=0 || hy0
>=0){
700 /* store new neighbor values */
701 for(j
=sortpos
-1;j
>=0;j
--)
702 if(hineighbor
[j
]==hn
)
706 for(j
=sortpos
+1;j
<posts
;j
++)
707 if(loneighbor
[j
]==ln
)
721 output
=_vorbis_block_alloc(vb
,sizeof(*output
)*posts
);
723 output
[0]=post_Y(fit_valueA
,fit_valueB
,0);
724 output
[1]=post_Y(fit_valueA
,fit_valueB
,1);
726 /* fill in posts marked as not using a fit; we will zero
727 back out to 'unused' when encoding them so long as curve
728 interpolation doesn't force them into use */
729 for(i
=2;i
<posts
;i
++){
730 int ln
=look
->loneighbor
[i
-2];
731 int hn
=look
->hineighbor
[i
-2];
732 int x0
=info
->postlist
[ln
];
733 int x1
=info
->postlist
[hn
];
737 int predicted
=render_point(x0
,x1
,y0
,y1
,info
->postlist
[i
]);
738 int vx
=post_Y(fit_valueA
,fit_valueB
,i
);
740 if(vx
>=0 && predicted
!=vx
){
743 output
[i
]= predicted
|0x8000;
752 int *floor1_interpolate_fit(vorbis_block
*vb
,vorbis_look_floor1
*look
,
757 long posts
=look
->posts
;
761 output
=_vorbis_block_alloc(vb
,sizeof(*output
)*posts
);
763 /* overly simpleminded--- look again post 1.2 */
764 for(i
=0;i
<posts
;i
++){
765 output
[i
]=((65536-del
)*(A
[i
]&0x7fff)+del
*(B
[i
]&0x7fff)+32768)>>16;
766 if(A
[i
]&0x8000 && B
[i
]&0x8000)output
[i
]|=0x8000;
774 int floor1_encode(oggpack_buffer
*opb
,vorbis_block
*vb
,
775 vorbis_look_floor1
*look
,
776 int *post
,int *ilogmask
){
779 vorbis_info_floor1
*info
=look
->vi
;
780 long posts
=look
->posts
;
781 codec_setup_info
*ci
=vb
->vd
->vi
->codec_setup
;
782 int out
[VIF_POSIT
+2];
783 static_codebook
**sbooks
=ci
->book_param
;
784 codebook
*books
=ci
->fullbooks
;
786 /* quantize values to multiplier spec */
788 for(i
=0;i
<posts
;i
++){
789 int val
=post
[i
]&0x7fff;
791 case 1: /* 1024 -> 256 */
794 case 2: /* 1024 -> 128 */
797 case 3: /* 1024 -> 86 */
800 case 4: /* 1024 -> 64 */
804 post
[i
]=val
| (post
[i
]&0x8000);
810 /* find prediction values for each post and subtract them */
811 for(i
=2;i
<posts
;i
++){
812 int ln
=look
->loneighbor
[i
-2];
813 int hn
=look
->hineighbor
[i
-2];
814 int x0
=info
->postlist
[ln
];
815 int x1
=info
->postlist
[hn
];
819 int predicted
=render_point(x0
,x1
,y0
,y1
,info
->postlist
[i
]);
821 if((post
[i
]&0x8000) || (predicted
==post
[i
])){
822 post
[i
]=predicted
|0x8000; /* in case there was roundoff jitter
826 int headroom
=(look
->quant_q
-predicted
<predicted
?
827 look
->quant_q
-predicted
:predicted
);
829 int val
=post
[i
]-predicted
;
831 /* at this point the 'deviation' value is in the range +/- max
832 range, but the real, unique range can always be mapped to
833 only [0-maxrange). So we want to wrap the deviation into
834 this limited range, but do it in the way that least screws
835 an essentially gaussian probability distribution. */
854 /* we have everything we need. pack it out */
855 /* mark nontrivial floor */
856 oggpack_write(opb
,1,1);
858 /* beginning/end post */
860 look
->postbits
+=ilog(look
->quant_q
-1)*2;
861 oggpack_write(opb
,out
[0],ilog(look
->quant_q
-1));
862 oggpack_write(opb
,out
[1],ilog(look
->quant_q
-1));
865 /* partition by partition */
866 for(i
=0,j
=2;i
<info
->partitions
;i
++){
867 int class=info
->partitionclass
[i
];
868 int cdim
=info
->class_dim
[class];
869 int csubbits
=info
->class_subs
[class];
870 int csub
=1<<csubbits
;
871 int bookas
[8]={0,0,0,0,0,0,0,0};
876 /* generate the partition's first stage cascade value */
880 int booknum
=info
->class_subbook
[class][k
];
884 maxval
[k
]=sbooks
[info
->class_subbook
[class][k
]]->entries
;
895 cval
|= bookas
[k
]<<cshift
;
900 vorbis_book_encode(books
+info
->class_book
[class],cval
,opb
);
906 sprintf(buffer
,"line_%dx%ld_class%d.vqd",
907 vb
->pcmend
/2,posts
-2,class);
908 of
=fopen(buffer
,"a");
909 fprintf(of
,"%d\n",cval
);
915 /* write post values */
917 int book
=info
->class_subbook
[class][bookas
[k
]];
919 /* hack to allow training with 'bad' books */
920 if(out
[j
+k
]<(books
+book
)->entries
)
921 look
->postbits
+=vorbis_book_encode(books
+book
,
924 fprintf(stderr,"+!");*/
930 sprintf(buffer
,"line_%dx%ld_%dsub%d.vqd",
931 vb
->pcmend
/2,posts
-2,class,bookas
[k
]);
932 of
=fopen(buffer
,"a");
933 fprintf(of
,"%d\n",out
[j
+k
]);
943 /* generate quantized floor equivalent to what we'd unpack in decode */
944 /* render the lines */
947 int ly
=post
[0]*info
->mult
;
948 for(j
=1;j
<look
->posts
;j
++){
949 int current
=look
->forward_index
[j
];
950 int hy
=post
[current
]&0x7fff;
951 if(hy
==post
[current
]){
954 hx
=info
->postlist
[current
];
956 render_line0(lx
,hx
,ly
,hy
,ilogmask
);
962 for(j
=hx
;j
<vb
->pcmend
/2;j
++)ilogmask
[j
]=ly
; /* be certain */
966 oggpack_write(opb
,0,1);
967 memset(ilogmask
,0,vb
->pcmend
/2*sizeof(*ilogmask
));
972 static void *floor1_inverse1(vorbis_block
*vb
,vorbis_look_floor
*in
){
973 vorbis_look_floor1
*look
=(vorbis_look_floor1
*)in
;
974 vorbis_info_floor1
*info
=look
->vi
;
975 codec_setup_info
*ci
=vb
->vd
->vi
->codec_setup
;
978 codebook
*books
=ci
->fullbooks
;
980 /* unpack wrapped/predicted values from stream */
981 if(oggpack_read(&vb
->opb
,1)==1){
982 int *fit_value
=_vorbis_block_alloc(vb
,(look
->posts
)*sizeof(*fit_value
));
984 fit_value
[0]=oggpack_read(&vb
->opb
,ilog(look
->quant_q
-1));
985 fit_value
[1]=oggpack_read(&vb
->opb
,ilog(look
->quant_q
-1));
987 /* partition by partition */
988 for(i
=0,j
=2;i
<info
->partitions
;i
++){
989 int class=info
->partitionclass
[i
];
990 int cdim
=info
->class_dim
[class];
991 int csubbits
=info
->class_subs
[class];
992 int csub
=1<<csubbits
;
995 /* decode the partition's first stage cascade value */
997 cval
=vorbis_book_decode(books
+info
->class_book
[class],&vb
->opb
);
999 if(cval
==-1)goto eop
;
1002 for(k
=0;k
<cdim
;k
++){
1003 int book
=info
->class_subbook
[class][cval
&(csub
-1)];
1006 if((fit_value
[j
+k
]=vorbis_book_decode(books
+book
,&vb
->opb
))==-1)
1015 /* unwrap positive values and reconsitute via linear interpolation */
1016 for(i
=2;i
<look
->posts
;i
++){
1017 int predicted
=render_point(info
->postlist
[look
->loneighbor
[i
-2]],
1018 info
->postlist
[look
->hineighbor
[i
-2]],
1019 fit_value
[look
->loneighbor
[i
-2]],
1020 fit_value
[look
->hineighbor
[i
-2]],
1022 int hiroom
=look
->quant_q
-predicted
;
1023 int loroom
=predicted
;
1024 int room
=(hiroom
<loroom
?hiroom
:loroom
)<<1;
1025 int val
=fit_value
[i
];
1032 val
= -1-(val
-hiroom
);
1042 fit_value
[i
]=val
+predicted
;
1043 fit_value
[look
->loneighbor
[i
-2]]&=0x7fff;
1044 fit_value
[look
->hineighbor
[i
-2]]&=0x7fff;
1047 fit_value
[i
]=predicted
|0x8000;
1058 static int floor1_inverse2(vorbis_block
*vb
,vorbis_look_floor
*in
,void *memo
,
1060 vorbis_look_floor1
*look
=(vorbis_look_floor1
*)in
;
1061 vorbis_info_floor1
*info
=look
->vi
;
1063 codec_setup_info
*ci
=vb
->vd
->vi
->codec_setup
;
1064 int n
=ci
->blocksizes
[vb
->W
]/2;
1068 /* render the lines */
1069 int *fit_value
=(int *)memo
;
1072 int ly
=fit_value
[0]*info
->mult
;
1073 for(j
=1;j
<look
->posts
;j
++){
1074 int current
=look
->forward_index
[j
];
1075 int hy
=fit_value
[current
]&0x7fff;
1076 if(hy
==fit_value
[current
]){
1079 hx
=info
->postlist
[current
];
1081 render_line(n
,lx
,hx
,ly
,hy
,out
);
1087 for(j
=hx
;j
<n
;j
++)out
[j
]*=FLOOR1_fromdB_LOOKUP
[ly
]; /* be certain */
1090 memset(out
,0,sizeof(*out
)*n
);
1095 const vorbis_func_floor floor1_exportbundle
={
1096 &floor1_pack
,&floor1_unpack
,&floor1_look
,&floor1_free_info
,
1097 &floor1_free_look
,&floor1_inverse1
,&floor1_inverse2