Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / libvorbis / lib / floor1.c
blobc031a236213ee4942cd9cf823aa0c4750a68a347
1 /********************************************************************
2 * *
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. *
7 * *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function: floor backend 1 implementation
14 last mod: $Id: floor1.c 16227 2009-07-08 06:58:46Z xiphmont $
16 ********************************************************************/
18 #include <stdlib.h>
19 #include <string.h>
20 #include <math.h>
21 #include <ogg/ogg.h>
22 #include "vorbis/codec.h"
23 #include "codec_internal.h"
24 #include "registry.h"
25 #include "codebook.h"
26 #include "misc.h"
27 #include "scales.h"
29 #include <stdio.h>
31 #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
33 typedef struct lsfit_acc{
34 long x0;
35 long x1;
37 long xa;
38 long ya;
39 long x2a;
40 long y2a;
41 long xya;
42 long an;
43 } lsfit_acc;
45 /***********************************************/
47 static void floor1_free_info(vorbis_info_floor *i){
48 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
49 if(info){
50 memset(info,0,sizeof(*info));
51 _ogg_free(info);
55 static void floor1_free_look(vorbis_look_floor *i){
56 vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
57 if(look){
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));
64 _ogg_free(look);
68 static int ilog(unsigned int v){
69 int ret=0;
70 while(v){
71 ret++;
72 v>>=1;
74 return(ret);
77 static int ilog2(unsigned int v){
78 int ret=0;
79 if(v)--v;
80 while(v){
81 ret++;
82 v>>=1;
84 return(ret);
87 static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
88 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
89 int j,k;
90 int count=0;
91 int rangebits;
92 int maxposit=info->postlist[1];
93 int maxclass=-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]];
118 for(;k<count;k++)
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)
145 goto err_out;
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)
148 goto err_out;
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)
152 goto err_out;
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]];
163 for(;k<count;k++){
164 int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
165 if(t<0 || t>=(1<<rangebits))
166 goto err_out;
169 info->postlist[0]=0;
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;
183 return(info);
185 err_out:
186 floor1_free_info(info);
187 return(NULL);
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));
196 int i,j,n=0;
198 look->vi=info;
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]];
209 n+=2;
210 look->posts=n;
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 */
224 switch(info->mult){
225 case 1: /* 1024 -> 256 */
226 look->quant_q=256;
227 break;
228 case 2: /* 1024 -> 128 */
229 look->quant_q=128;
230 break;
231 case 3: /* 1024 -> 86 */
232 look->quant_q=86;
233 break;
234 case 4: /* 1024 -> 64 */
235 look->quant_q=64;
236 break;
239 /* discover our neighbors for decode where we don't use fit flags
240 (that would push the neighbors outward) */
241 for(i=0;i<n-2;i++){
242 int lo=0;
243 int hi=1;
244 int lx=0;
245 int hx=look->n;
246 int currentx=info->postlist[i+2];
247 for(j=0;j<i+2;j++){
248 int x=info->postlist[j];
249 if(x>lx && x<currentx){
250 lo=j;
251 lx=x;
253 if(x<hx && x>currentx){
254 hi=j;
255 hx=x;
258 look->loneighbor[i]=lo;
259 look->hineighbor[i]=hi;
262 return(look);
265 static int render_point(int x0,int x1,int y0,int y1,int x){
266 y0&=0x7fff; /* mask off flag */
267 y1&=0x7fff;
270 int dy=y1-y0;
271 int adx=x1-x0;
272 int ady=abs(dy);
273 int err=ady*(x-x0);
275 int off=err/adx;
276 if(dy<0)return(y0-off);
277 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);
284 if(i<0)return(0);
285 return i;
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){
356 int dy=y1-y0;
357 int adx=x1-x0;
358 int ady=abs(dy);
359 int base=dy/adx;
360 int sy=(dy<0?base-1:base+1);
361 int x=x0;
362 int y=y0;
363 int err=0;
365 ady-=abs(base*adx);
367 if(n>x1)n=x1;
369 if(x<n)
370 d[x]*=FLOOR1_fromdB_LOOKUP[y];
372 while(++x<n){
373 err=err+ady;
374 if(err>=adx){
375 err-=adx;
376 y+=sy;
377 }else{
378 y+=base;
380 d[x]*=FLOOR1_fromdB_LOOKUP[y];
384 static void render_line0(int x0,int x1,int y0,int y1,int *d){
385 int dy=y1-y0;
386 int adx=x1-x0;
387 int ady=abs(dy);
388 int base=dy/adx;
389 int sy=(dy<0?base-1:base+1);
390 int x=x0;
391 int y=y0;
392 int err=0;
394 ady-=abs(base*adx);
396 d[x]=y;
397 while(++x<x1){
398 err=err+ady;
399 if(err>=adx){
400 err-=adx;
401 y+=sy;
402 }else{
403 y+=base;
405 d[x]=y;
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){
413 long i;
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));
418 a->x0=x0;
419 a->x1=x1;
420 if(x1>=n)x1=n-1;
422 for(i=x0;i<=x1;i++){
423 int quantized=vorbis_dBquant(flr+i);
424 if(quantized){
425 if(mdct[i]+info->twofitatten>=flr[i]){
426 xa += i;
427 ya += quantized;
428 x2a += i*i;
429 y2a += quantized*quantized;
430 xya += i*quantized;
431 na++;
432 }else{
433 xb += i;
434 yb += quantized;
435 x2b += i*i;
436 y2b += quantized*quantized;
437 xyb += i*quantized;
438 nb++;
443 xb+=xa;
444 yb+=ya;
445 x2b+=x2a;
446 y2b+=y2a;
447 xyb+=xya;
448 nb+=na;
450 /* weight toward the actually used frequencies if we meet the threshhold */
452 int weight=nb*info->twofitweight/(na+1);
454 a->xa=xa*weight+xb;
455 a->ya=ya*weight+yb;
456 a->x2a=x2a*weight+x2b;
457 a->y2a=y2a*weight+y2b;
458 a->xya=xya*weight+xyb;
459 a->an=na*weight+nb;
462 return(na);
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;
467 long x0=a[0].x0;
468 long x1=a[fits-1].x1;
470 for(i=0;i<fits;i++){
471 x+=a[i].xa;
472 y+=a[i].ya;
473 x2+=a[i].x2a;
474 y2+=a[i].y2a;
475 xy+=a[i].xya;
476 an+=a[i].an;
479 if(*y0>=0){
480 x+= x0;
481 y+= *y0;
482 x2+= x0 * x0;
483 y2+= *y0 * *y0;
484 xy+= *y0 * x0;
485 an++;
488 if(*y1>=0){
489 x+= x1;
490 y+= *y1;
491 x2+= x1 * x1;
492 y2+= *y1 * *y1;
493 xy+= *y1 * x1;
494 an++;
498 /* need 64 bit multiplies, which C doesn't give portably as int */
499 double fx=x;
500 double fx2=x2;
501 double denom=(an*fx2-fx*fx);
503 if(denom>0.){
504 double fy=y;
505 double fxy=xy;
507 double a=(fy*fx2-fxy*fx)/denom;
508 double b=(an*fxy-fx*fy)/denom;
509 *y0=rint(a+b*x0);
510 *y1=rint(a+b*x1);
512 /* limit to our range! */
513 if(*y0>1023)*y0=1023;
514 if(*y1>1023)*y1=1023;
515 if(*y0<0)*y0=0;
516 if(*y1<0)*y1=0;
518 return 0;
519 }else{
520 *y0=0;
521 *y1=0;
522 return 1;
527 /*static void fit_line_point(lsfit_acc *a,int fits,int *y0,int *y1){
528 long y=0;
529 int i;
531 for(i=0;i<fits && y==0;i++)
532 y+=a[i].ya;
534 *y0=*y1=y;
537 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
538 const float *mdct,
539 vorbis_info_floor1 *info){
540 int dy=y1-y0;
541 int adx=x1-x0;
542 int ady=abs(dy);
543 int base=dy/adx;
544 int sy=(dy<0?base-1:base+1);
545 int x=x0;
546 int y=y0;
547 int err=0;
548 int val=vorbis_dBquant(mask+x);
549 int mse=0;
550 int n=0;
552 ady-=abs(base*adx);
554 mse=(y-val);
555 mse*=mse;
556 n++;
557 if(mdct[x]+info->twofitatten>=mask[x]){
558 if(y+info->maxover<val)return(1);
559 if(y-info->maxunder>val)return(1);
562 while(++x<x1){
563 err=err+ady;
564 if(err>=adx){
565 err-=adx;
566 y+=sy;
567 }else{
568 y+=base;
571 val=vorbis_dBquant(mask+x);
572 mse+=((y-val)*(y-val));
573 n++;
574 if(mdct[x]+info->twofitatten>=mask[x]){
575 if(val){
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);
585 return(0);
588 static int post_Y(int *A,int *B,int pos){
589 if(A[pos]<0)
590 return B[pos];
591 if(B[pos]<0)
592 return A[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){
600 long i,j;
601 vorbis_info_floor1 *info=look->vi;
602 long n=look->n;
603 long posts=look->posts;
604 long nonzero=0;
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];
611 int *output=NULL;
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 */
622 if(posts==0){
623 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
624 }else{
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,
628 n,info);
631 if(nonzero){
632 /* start by fitting the implicit base case.... */
633 int y0=-200;
634 int y1=-200;
635 fit_line(fits,posts-1,&y0,&y1);
637 fit_valueA[0]=y0;
638 fit_valueB[0]=y0;
639 fit_valueB[1]=y1;
640 fit_valueA[1]=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
645 answer. */
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 */
652 if(memo[ln]!=hn){
653 /* haven't performed this error search yet */
654 int lsortpos=look->reverse_index[ln];
655 int hsortpos=look->reverse_index[hn];
656 memo[ln]=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){
666 exit(1);
669 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
670 /* outside error bounds/begin search area. Split it. */
671 int ly0=-200;
672 int ly1=-200;
673 int hy0=-200;
674 int hy1=-200;
675 int ret0=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1);
676 int ret1=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1);
678 if(ret0){
679 ly0=ly;
680 ly1=hy0;
682 if(ret1){
683 hy0=ly1;
684 hy1=hy;
687 if(ret0 && ret1){
688 fit_valueA[i]=-200;
689 fit_valueB[i]=-200;
690 }else{
691 /* store new edge values */
692 fit_valueB[ln]=ly0;
693 if(ln==0)fit_valueA[ln]=ly0;
694 fit_valueA[i]=ly1;
695 fit_valueB[i]=hy0;
696 fit_valueA[hn]=hy1;
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)
703 hineighbor[j]=i;
704 else
705 break;
706 for(j=sortpos+1;j<posts;j++)
707 if(loneighbor[j]==ln)
708 loneighbor[j]=i;
709 else
710 break;
713 }else{
714 fit_valueA[i]=-200;
715 fit_valueB[i]=-200;
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];
734 int y0=output[ln];
735 int y1=output[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){
741 output[i]=vx;
742 }else{
743 output[i]= predicted|0x8000;
748 return(output);
752 int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
753 int *A,int *B,
754 int del){
756 long i;
757 long posts=look->posts;
758 int *output=NULL;
760 if(A && B){
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;
770 return(output);
774 int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
775 vorbis_look_floor1 *look,
776 int *post,int *ilogmask){
778 long i,j;
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 */
787 if(post){
788 for(i=0;i<posts;i++){
789 int val=post[i]&0x7fff;
790 switch(info->mult){
791 case 1: /* 1024 -> 256 */
792 val>>=2;
793 break;
794 case 2: /* 1024 -> 128 */
795 val>>=3;
796 break;
797 case 3: /* 1024 -> 86 */
798 val/=12;
799 break;
800 case 4: /* 1024 -> 64 */
801 val>>=4;
802 break;
804 post[i]=val | (post[i]&0x8000);
807 out[0]=post[0];
808 out[1]=post[1];
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];
816 int y0=post[ln];
817 int y1=post[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
823 in interpolation */
824 out[i]=0;
825 }else{
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. */
837 if(val<0)
838 if(val<-headroom)
839 val=headroom-val-1;
840 else
841 val=-1-(val<<1);
842 else
843 if(val>=headroom)
844 val= val+headroom;
845 else
846 val<<=1;
848 out[i]=val;
849 post[ln]&=0x7fff;
850 post[hn]&=0x7fff;
854 /* we have everything we need. pack it out */
855 /* mark nontrivial floor */
856 oggpack_write(opb,1,1);
858 /* beginning/end post */
859 look->frames++;
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};
872 int cval=0;
873 int cshift=0;
874 int k,l;
876 /* generate the partition's first stage cascade value */
877 if(csubbits){
878 int maxval[8];
879 for(k=0;k<csub;k++){
880 int booknum=info->class_subbook[class][k];
881 if(booknum<0){
882 maxval[k]=1;
883 }else{
884 maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
887 for(k=0;k<cdim;k++){
888 for(l=0;l<csub;l++){
889 int val=out[j+k];
890 if(val<maxval[l]){
891 bookas[k]=l;
892 break;
895 cval|= bookas[k]<<cshift;
896 cshift+=csubbits;
898 /* write it */
899 look->phrasebits+=
900 vorbis_book_encode(books+info->class_book[class],cval,opb);
902 #ifdef TRAIN_FLOOR1
904 FILE *of;
905 char buffer[80];
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);
910 fclose(of);
912 #endif
915 /* write post values */
916 for(k=0;k<cdim;k++){
917 int book=info->class_subbook[class][bookas[k]];
918 if(book>=0){
919 /* hack to allow training with 'bad' books */
920 if(out[j+k]<(books+book)->entries)
921 look->postbits+=vorbis_book_encode(books+book,
922 out[j+k],opb);
923 /*else
924 fprintf(stderr,"+!");*/
926 #ifdef TRAIN_FLOOR1
928 FILE *of;
929 char buffer[80];
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]);
934 fclose(of);
936 #endif
939 j+=cdim;
943 /* generate quantized floor equivalent to what we'd unpack in decode */
944 /* render the lines */
945 int hx=0;
946 int lx=0;
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]){
953 hy*=info->mult;
954 hx=info->postlist[current];
956 render_line0(lx,hx,ly,hy,ilogmask);
958 lx=hx;
959 ly=hy;
962 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
963 return(1);
965 }else{
966 oggpack_write(opb,0,1);
967 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
968 return(0);
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;
977 int i,j,k;
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;
993 int cval=0;
995 /* decode the partition's first stage cascade value */
996 if(csubbits){
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)];
1004 cval>>=csubbits;
1005 if(book>=0){
1006 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
1007 goto eop;
1008 }else{
1009 fit_value[j+k]=0;
1012 j+=cdim;
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]],
1021 info->postlist[i]);
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];
1027 if(val){
1028 if(val>=room){
1029 if(hiroom>loroom){
1030 val = val-loroom;
1031 }else{
1032 val = -1-(val-hiroom);
1034 }else{
1035 if(val&1){
1036 val= -((val+1)>>1);
1037 }else{
1038 val>>=1;
1042 fit_value[i]=val+predicted;
1043 fit_value[look->loneighbor[i-2]]&=0x7fff;
1044 fit_value[look->hineighbor[i-2]]&=0x7fff;
1046 }else{
1047 fit_value[i]=predicted|0x8000;
1052 return(fit_value);
1054 eop:
1055 return(NULL);
1058 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1059 float *out){
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;
1065 int j;
1067 if(memo){
1068 /* render the lines */
1069 int *fit_value=(int *)memo;
1070 int hx=0;
1071 int lx=0;
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]){
1078 hy*=info->mult;
1079 hx=info->postlist[current];
1081 render_line(n,lx,hx,ly,hy,out);
1083 lx=hx;
1084 ly=hy;
1087 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1088 return(1);
1090 memset(out,0,sizeof(*out)*n);
1091 return(0);
1094 /* export hooks */
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