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 ******************************************************************** 12 13 function: floor backend 1 implementation 14 last mod: $Id: floor1.c 17079 2010-03-26 06:51:41Z xiphmont $ 15 16 ********************************************************************/ 17 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" 28 29 #include <stdio.h> 30 31 #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */ 32 33 typedef struct lsfit_acc{ 34 int x0; 35 int x1; 36 37 int xa; 38 int ya; 39 int x2a; 40 int y2a; 41 int xya; 42 int an; 43 44 int xb; 45 int yb; 46 int x2b; 47 int y2b; 48 int xyb; 49 int bn; 50 } lsfit_acc; 51 52 /***********************************************/ 53 54 static void floor1_free_info(vorbis_info_floor *i){ 55 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; 56 if(info){ 57 memset(info,0,sizeof(*info)); 58 _ogg_free(info); 59 } 60 } 61 62 static void floor1_free_look(vorbis_look_floor *i){ 63 vorbis_look_floor1 *look=(vorbis_look_floor1 *)i; 64 if(look){ 65 /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n", 66 (float)look->phrasebits/look->frames, 67 (float)look->postbits/look->frames, 68 (float)(look->postbits+look->phrasebits)/look->frames);*/ 69 70 memset(look,0,sizeof(*look)); 71 _ogg_free(look); 72 } 73 } 74 75 static int ilog(unsigned int v){ 76 int ret=0; 77 while(v){ 78 ret++; 79 v>>=1; 80 } 81 return(ret); 82 } 83 84 static int ilog2(unsigned int v){ 85 int ret=0; 86 if(v)--v; 87 while(v){ 88 ret++; 89 v>>=1; 90 } 91 return(ret); 92 } 93 94 static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){ 95 vorbis_info_floor1 *info=(vorbis_info_floor1 *)i; 96 int j,k; 97 int count=0; 98 int rangebits; 99 int maxposit=info->postlist[1]; 100 int maxclass=-1; 101 102 /* save out partitions */ 103 oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */ 104 for(j=0;j<info->partitions;j++){ 105 oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */ 106 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j]; 107 } 108 109 /* save out partition classes */ 110 for(j=0;j<maxclass+1;j++){ 111 oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */ 112 oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */ 113 if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8); 114 for(k=0;k<(1<<info->class_subs[j]);k++) 115 oggpack_write(opb,info->class_subbook[j][k]+1,8); 116 } 117 118 /* save out the post list */ 119 oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */ 120 oggpack_write(opb,ilog2(maxposit),4); 121 rangebits=ilog2(maxposit); 122 123 for(j=0,k=0;j<info->partitions;j++){ 124 count+=info->class_dim[info->partitionclass[j]]; 125 for(;k<count;k++) 126 oggpack_write(opb,info->postlist[k+2],rangebits); 127 } 128 } 129 130 static int icomp(const void *a,const void *b){ 131 return(**(int **)a-**(int **)b); 132 } 133 134 static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){ 135 codec_setup_info *ci=vi->codec_setup; 136 int j,k,count=0,maxclass=-1,rangebits; 137 138 vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info)); 139 /* read partitions */ 140 info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */ 141 for(j=0;j<info->partitions;j++){ 142 info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */ 143 if(info->partitionclass[j]<0)goto err_out; 144 if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j]; 145 } 146 147 /* read partition classes */ 148 for(j=0;j<maxclass+1;j++){ 149 info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */ 150 info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */ 151 if(info->class_subs[j]<0) 152 goto err_out; 153 if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8); 154 if(info->class_book[j]<0 || info->class_book[j]>=ci->books) 155 goto err_out; 156 for(k=0;k<(1<<info->class_subs[j]);k++){ 157 info->class_subbook[j][k]=oggpack_read(opb,8)-1; 158 if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books) 159 goto err_out; 160 } 161 } 162 163 /* read the post list */ 164 info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */ 165 rangebits=oggpack_read(opb,4); 166 if(rangebits<0)goto err_out; 167 168 for(j=0,k=0;j<info->partitions;j++){ 169 count+=info->class_dim[info->partitionclass[j]]; 170 for(;k<count;k++){ 171 int t=info->postlist[k+2]=oggpack_read(opb,rangebits); 172 if(t<0 || t>=(1<<rangebits)) 173 goto err_out; 174 } 175 } 176 info->postlist[0]=0; 177 info->postlist[1]=1<<rangebits; 178 179 /* don't allow repeated values in post list as they'd result in 180 zero-length segments */ 181 { 182 int *sortpointer[VIF_POSIT+2]; 183 for(j=0;j<count+2;j++)sortpointer[j]=info->postlist+j; 184 qsort(sortpointer,count+2,sizeof(*sortpointer),icomp); 185 186 for(j=1;j<count+2;j++) 187 if(*sortpointer[j-1]==*sortpointer[j])goto err_out; 188 } 189 190 return(info); 191 192 err_out: 193 floor1_free_info(info); 194 return(NULL); 195 } 196 197 static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd, 198 vorbis_info_floor *in){ 199 200 int *sortpointer[VIF_POSIT+2]; 201 vorbis_info_floor1 *info=(vorbis_info_floor1 *)in; 202 vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(*look)); 203 int i,j,n=0; 204 205 look->vi=info; 206 look->n=info->postlist[1]; 207 208 /* we drop each position value in-between already decoded values, 209 and use linear interpolation to predict each new value past the 210 edges. The positions are read in the order of the position 211 list... we precompute the bounding positions in the lookup. Of 212 course, the neighbors can change (if a position is declined), but 213 this is an initial mapping */ 214 215 for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]]; 216 n+=2; 217 look->posts=n; 218 219 /* also store a sorted position index */ 220 for(i=0;i<n;i++)sortpointer[i]=info->postlist+i; 221 qsort(sortpointer,n,sizeof(*sortpointer),icomp); 222 223 /* points from sort order back to range number */ 224 for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist; 225 /* points from range order to sorted position */ 226 for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i; 227 /* we actually need the post values too */ 228 for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]]; 229 230 /* quantize values to multiplier spec */ 231 switch(info->mult){ 232 case 1: /* 1024 -> 256 */ 233 look->quant_q=256; 234 break; 235 case 2: /* 1024 -> 128 */ 236 look->quant_q=128; 237 break; 238 case 3: /* 1024 -> 86 */ 239 look->quant_q=86; 240 break; 241 case 4: /* 1024 -> 64 */ 242 look->quant_q=64; 243 break; 244 } 245 246 /* discover our neighbors for decode where we don't use fit flags 247 (that would push the neighbors outward) */ 248 for(i=0;i<n-2;i++){ 249 int lo=0; 250 int hi=1; 251 int lx=0; 252 int hx=look->n; 253 int currentx=info->postlist[i+2]; 254 for(j=0;j<i+2;j++){ 255 int x=info->postlist[j]; 256 if(x>lx && x<currentx){ 257 lo=j; 258 lx=x; 259 } 260 if(x<hx && x>currentx){ 261 hi=j; 262 hx=x; 263 } 264 } 265 look->loneighbor[i]=lo; 266 look->hineighbor[i]=hi; 267 } 268 269 return(look); 270 } 271 272 static int render_point(int x0,int x1,int y0,int y1,int x){ 273 y0&=0x7fff; /* mask off flag */ 274 y1&=0x7fff; 275 276 { 277 int dy=y1-y0; 278 int adx=x1-x0; 279 int ady=abs(dy); 280 int err=ady*(x-x0); 281 282 int off=err/adx; 283 if(dy<0)return(y0-off); 284 return(y0+off); 285 } 286 } 287 288 static int vorbis_dBquant(const float *x){ 289 int i= *x*7.3142857f+1023.5f; 290 if(i>1023)return(1023); 291 if(i<0)return(0); 292 return i; 293 } 294 295 static const float FLOOR1_fromdB_LOOKUP[256]={ 296 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, 297 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, 298 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, 299 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, 300 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, 301 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, 302 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, 303 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, 304 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, 305 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, 306 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, 307 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, 308 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, 309 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, 310 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, 311 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, 312 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, 313 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, 314 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, 315 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, 316 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, 317 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, 318 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, 319 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, 320 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, 321 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, 322 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, 323 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, 324 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, 325 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, 326 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, 327 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, 328 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, 329 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, 330 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, 331 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, 332 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, 333 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, 334 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, 335 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, 336 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, 337 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, 338 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, 339 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, 340 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, 341 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, 342 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, 343 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, 344 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, 345 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, 346 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, 347 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, 348 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, 349 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, 350 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, 351 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, 352 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, 353 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, 354 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, 355 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, 356 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, 357 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, 358 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, 359 0.82788260F, 0.88168307F, 0.9389798F, 1.F, 360 }; 361 362 static void render_line(int n, int x0,int x1,int y0,int y1,float *d){ 363 int dy=y1-y0; 364 int adx=x1-x0; 365 int ady=abs(dy); 366 int base=dy/adx; 367 int sy=(dy<0?base-1:base+1); 368 int x=x0; 369 int y=y0; 370 int err=0; 371 372 ady-=abs(base*adx); 373 374 if(n>x1)n=x1; 375 376 if(x<n) 377 d[x]*=FLOOR1_fromdB_LOOKUP[y]; 378 379 while(++x<n){ 380 err=err+ady; 381 if(err>=adx){ 382 err-=adx; 383 y+=sy; 384 }else{ 385 y+=base; 386 } 387 d[x]*=FLOOR1_fromdB_LOOKUP[y]; 388 } 389 } 390 391 static void render_line0(int n, int x0,int x1,int y0,int y1,int *d){ 392 int dy=y1-y0; 393 int adx=x1-x0; 394 int ady=abs(dy); 395 int base=dy/adx; 396 int sy=(dy<0?base-1:base+1); 397 int x=x0; 398 int y=y0; 399 int err=0; 400 401 ady-=abs(base*adx); 402 403 if(n>x1)n=x1; 404 405 if(x<n) 406 d[x]=y; 407 408 while(++x<n){ 409 err=err+ady; 410 if(err>=adx){ 411 err-=adx; 412 y+=sy; 413 }else{ 414 y+=base; 415 } 416 d[x]=y; 417 } 418 } 419 420 /* the floor has already been filtered to only include relevant sections */ 421 static int accumulate_fit(const float *flr,const float *mdct, 422 int x0, int x1,lsfit_acc *a, 423 int n,vorbis_info_floor1 *info){ 424 long i; 425 426 int xa=0,ya=0,x2a=0,y2a=0,xya=0,na=0, xb=0,yb=0,x2b=0,y2b=0,xyb=0,nb=0; 427 428 memset(a,0,sizeof(*a)); 429 a->x0=x0; 430 a->x1=x1; 431 if(x1>=n)x1=n-1; 432 433 for(i=x0;i<=x1;i++){ 434 int quantized=vorbis_dBquant(flr+i); 435 if(quantized){ 436 if(mdct[i]+info->twofitatten>=flr[i]){ 437 xa += i; 438 ya += quantized; 439 x2a += i*i; 440 y2a += quantized*quantized; 441 xya += i*quantized; 442 na++; 443 }else{ 444 xb += i; 445 yb += quantized; 446 x2b += i*i; 447 y2b += quantized*quantized; 448 xyb += i*quantized; 449 nb++; 450 } 451 } 452 } 453 454 a->xa=xa; 455 a->ya=ya; 456 a->x2a=x2a; 457 a->y2a=y2a; 458 a->xya=xya; 459 a->an=na; 460 461 a->xb=xb; 462 a->yb=yb; 463 a->x2b=x2b; 464 a->y2b=y2b; 465 a->xyb=xyb; 466 a->bn=nb; 467 468 return(na); 469 } 470 471 static int fit_line(lsfit_acc *a,int fits,int *y0,int *y1, 472 vorbis_info_floor1 *info){ 473 double xb=0,yb=0,x2b=0,y2b=0,xyb=0,bn=0; 474 int i; 475 int x0=a[0].x0; 476 int x1=a[fits-1].x1; 477 478 for(i=0;i<fits;i++){ 479 double weight = (a[i].bn+a[i].an)*info->twofitweight/(a[i].an+1)+1.; 480 481 xb+=a[i].xb + a[i].xa * weight; 482 yb+=a[i].yb + a[i].ya * weight; 483 x2b+=a[i].x2b + a[i].x2a * weight; 484 y2b+=a[i].y2b + a[i].y2a * weight; 485 xyb+=a[i].xyb + a[i].xya * weight; 486 bn+=a[i].bn + a[i].an * weight; 487 } 488 489 if(*y0>=0){ 490 xb+= x0; 491 yb+= *y0; 492 x2b+= x0 * x0; 493 y2b+= *y0 * *y0; 494 xyb+= *y0 * x0; 495 bn++; 496 } 497 498 if(*y1>=0){ 499 xb+= x1; 500 yb+= *y1; 501 x2b+= x1 * x1; 502 y2b+= *y1 * *y1; 503 xyb+= *y1 * x1; 504 bn++; 505 } 506 507 { 508 double denom=(bn*x2b-xb*xb); 509 510 if(denom>0.){ 511 double a=(yb*x2b-xyb*xb)/denom; 512 double b=(bn*xyb-xb*yb)/denom; 513 *y0=rint(a+b*x0); 514 *y1=rint(a+b*x1); 515 516 /* limit to our range! */ 517 if(*y0>1023)*y0=1023; 518 if(*y1>1023)*y1=1023; 519 if(*y0<0)*y0=0; 520 if(*y1<0)*y1=0; 521 522 return 0; 523 }else{ 524 *y0=0; 525 *y1=0; 526 return 1; 527 } 528 } 529 } 530 531 static int inspect_error(int x0,int x1,int y0,int y1,const float *mask, 532 const float *mdct, 533 vorbis_info_floor1 *info){ 534 int dy=y1-y0; 535 int adx=x1-x0; 536 int ady=abs(dy); 537 int base=dy/adx; 538 int sy=(dy<0?base-1:base+1); 539 int x=x0; 540 int y=y0; 541 int err=0; 542 int val=vorbis_dBquant(mask+x); 543 int mse=0; 544 int n=0; 545 546 ady-=abs(base*adx); 547 548 mse=(y-val); 549 mse*=mse; 550 n++; 551 if(mdct[x]+info->twofitatten>=mask[x]){ 552 if(y+info->maxover<val)return(1); 553 if(y-info->maxunder>val)return(1); 554 } 555 556 while(++x<x1){ 557 err=err+ady; 558 if(err>=adx){ 559 err-=adx; 560 y+=sy; 561 }else{ 562 y+=base; 563 } 564 565 val=vorbis_dBquant(mask+x); 566 mse+=((y-val)*(y-val)); 567 n++; 568 if(mdct[x]+info->twofitatten>=mask[x]){ 569 if(val){ 570 if(y+info->maxover<val)return(1); 571 if(y-info->maxunder>val)return(1); 572 } 573 } 574 } 575 576 if(info->maxover*info->maxover/n>info->maxerr)return(0); 577 if(info->maxunder*info->maxunder/n>info->maxerr)return(0); 578 if(mse/n>info->maxerr)return(1); 579 return(0); 580 } 581 582 static int post_Y(int *A,int *B,int pos){ 583 if(A[pos]<0) 584 return B[pos]; 585 if(B[pos]<0) 586 return A[pos]; 587 588 return (A[pos]+B[pos])>>1; 589 } 590 591 int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look, 592 const float *logmdct, /* in */ 593 const float *logmask){ 594 long i,j; 595 vorbis_info_floor1 *info=look->vi; 596 long n=look->n; 597 long posts=look->posts; 598 long nonzero=0; 599 lsfit_acc fits[VIF_POSIT+1]; 600 int fit_valueA[VIF_POSIT+2]; /* index by range list position */ 601 int fit_valueB[VIF_POSIT+2]; /* index by range list position */ 602 603 int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */ 604 int hineighbor[VIF_POSIT+2]; 605 int *output=NULL; 606 int memo[VIF_POSIT+2]; 607 608 for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */ 609 for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */ 610 for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */ 611 for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */ 612 for(i=0;i<posts;i++)memo[i]=-1; /* no neighbor yet */ 613 614 /* quantize the relevant floor points and collect them into line fit 615 structures (one per minimal division) at the same time */ 616 if(posts==0){ 617 nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info); 618 }else{ 619 for(i=0;i<posts-1;i++) 620 nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i], 621 look->sorted_index[i+1],fits+i, 622 n,info); 623 } 624 625 if(nonzero){ 626 /* start by fitting the implicit base case.... */ 627 int y0=-200; 628 int y1=-200; 629 fit_line(fits,posts-1,&y0,&y1,info); 630 631 fit_valueA[0]=y0; 632 fit_valueB[0]=y0; 633 fit_valueB[1]=y1; 634 fit_valueA[1]=y1; 635 636 /* Non degenerate case */ 637 /* start progressive splitting. This is a greedy, non-optimal 638 algorithm, but simple and close enough to the best 639 answer. */ 640 for(i=2;i<posts;i++){ 641 int sortpos=look->reverse_index[i]; 642 int ln=loneighbor[sortpos]; 643 int hn=hineighbor[sortpos]; 644 645 /* eliminate repeat searches of a particular range with a memo */ 646 if(memo[ln]!=hn){ 647 /* haven't performed this error search yet */ 648 int lsortpos=look->reverse_index[ln]; 649 int hsortpos=look->reverse_index[hn]; 650 memo[ln]=hn; 651 652 { 653 /* A note: we want to bound/minimize *local*, not global, error */ 654 int lx=info->postlist[ln]; 655 int hx=info->postlist[hn]; 656 int ly=post_Y(fit_valueA,fit_valueB,ln); 657 int hy=post_Y(fit_valueA,fit_valueB,hn); 658 659 if(ly==-1 || hy==-1){ 660 exit(1); 661 } 662 663 if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){ 664 /* outside error bounds/begin search area. Split it. */ 665 int ly0=-200; 666 int ly1=-200; 667 int hy0=-200; 668 int hy1=-200; 669 int ret0=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1,info); 670 int ret1=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1,info); 671 672 if(ret0){ 673 ly0=ly; 674 ly1=hy0; 675 } 676 if(ret1){ 677 hy0=ly1; 678 hy1=hy; 679 } 680 681 if(ret0 && ret1){ 682 fit_valueA[i]=-200; 683 fit_valueB[i]=-200; 684 }else{ 685 /* store new edge values */ 686 fit_valueB[ln]=ly0; 687 if(ln==0)fit_valueA[ln]=ly0; 688 fit_valueA[i]=ly1; 689 fit_valueB[i]=hy0; 690 fit_valueA[hn]=hy1; 691 if(hn==1)fit_valueB[hn]=hy1; 692 693 if(ly1>=0 || hy0>=0){ 694 /* store new neighbor values */ 695 for(j=sortpos-1;j>=0;j--) 696 if(hineighbor[j]==hn) 697 hineighbor[j]=i; 698 else 699 break; 700 for(j=sortpos+1;j<posts;j++) 701 if(loneighbor[j]==ln) 702 loneighbor[j]=i; 703 else 704 break; 705 } 706 } 707 }else{ 708 fit_valueA[i]=-200; 709 fit_valueB[i]=-200; 710 } 711 } 712 } 713 } 714 715 output=_vorbis_block_alloc(vb,sizeof(*output)*posts); 716 717 output[0]=post_Y(fit_valueA,fit_valueB,0); 718 output[1]=post_Y(fit_valueA,fit_valueB,1); 719 720 /* fill in posts marked as not using a fit; we will zero 721 back out to 'unused' when encoding them so long as curve 722 interpolation doesn't force them into use */ 723 for(i=2;i<posts;i++){ 724 int ln=look->loneighbor[i-2]; 725 int hn=look->hineighbor[i-2]; 726 int x0=info->postlist[ln]; 727 int x1=info->postlist[hn]; 728 int y0=output[ln]; 729 int y1=output[hn]; 730 731 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]); 732 int vx=post_Y(fit_valueA,fit_valueB,i); 733 734 if(vx>=0 && predicted!=vx){ 735 output[i]=vx; 736 }else{ 737 output[i]= predicted|0x8000; 738 } 739 } 740 } 741 742 return(output); 743 744 } 745 746 int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look, 747 int *A,int *B, 748 int del){ 749 750 long i; 751 long posts=look->posts; 752 int *output=NULL; 753 754 if(A && B){ 755 output=_vorbis_block_alloc(vb,sizeof(*output)*posts); 756 757 /* overly simpleminded--- look again post 1.2 */ 758 for(i=0;i<posts;i++){ 759 output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16; 760 if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000; 761 } 762 } 763 764 return(output); 765 } 766 767 768 int floor1_encode(oggpack_buffer *opb,vorbis_block *vb, 769 vorbis_look_floor1 *look, 770 int *post,int *ilogmask){ 771 772 long i,j; 773 vorbis_info_floor1 *info=look->vi; 774 long posts=look->posts; 775 codec_setup_info *ci=vb->vd->vi->codec_setup; 776 int out[VIF_POSIT+2]; 777 static_codebook **sbooks=ci->book_param; 778 codebook *books=ci->fullbooks; 779 780 /* quantize values to multiplier spec */ 781 if(post){ 782 for(i=0;i<posts;i++){ 783 int val=post[i]&0x7fff; 784 switch(info->mult){ 785 case 1: /* 1024 -> 256 */ 786 val>>=2; 787 break; 788 case 2: /* 1024 -> 128 */ 789 val>>=3; 790 break; 791 case 3: /* 1024 -> 86 */ 792 val/=12; 793 break; 794 case 4: /* 1024 -> 64 */ 795 val>>=4; 796 break; 797 } 798 post[i]=val | (post[i]&0x8000); 799 } 800 801 out[0]=post[0]; 802 out[1]=post[1]; 803 804 /* find prediction values for each post and subtract them */ 805 for(i=2;i<posts;i++){ 806 int ln=look->loneighbor[i-2]; 807 int hn=look->hineighbor[i-2]; 808 int x0=info->postlist[ln]; 809 int x1=info->postlist[hn]; 810 int y0=post[ln]; 811 int y1=post[hn]; 812 813 int predicted=render_point(x0,x1,y0,y1,info->postlist[i]); 814 815 if((post[i]&0x8000) || (predicted==post[i])){ 816 post[i]=predicted|0x8000; /* in case there was roundoff jitter 817 in interpolation */ 818 out[i]=0; 819 }else{ 820 int headroom=(look->quant_q-predicted<predicted? 821 look->quant_q-predicted:predicted); 822 823 int val=post[i]-predicted; 824 825 /* at this point the 'deviation' value is in the range +/- max 826 range, but the real, unique range can always be mapped to 827 only [0-maxrange). So we want to wrap the deviation into 828 this limited range, but do it in the way that least screws 829 an essentially gaussian probability distribution. */ 830 831 if(val<0) 832 if(val<-headroom) 833 val=headroom-val-1; 834 else 835 val=-1-(val<<1); 836 else 837 if(val>=headroom) 838 val= val+headroom; 839 else 840 val<<=1; 841 842 out[i]=val; 843 post[ln]&=0x7fff; 844 post[hn]&=0x7fff; 845 } 846 } 847 848 /* we have everything we need. pack it out */ 849 /* mark nontrivial floor */ 850 oggpack_write(opb,1,1); 851 852 /* beginning/end post */ 853 look->frames++; 854 look->postbits+=ilog(look->quant_q-1)*2; 855 oggpack_write(opb,out[0],ilog(look->quant_q-1)); 856 oggpack_write(opb,out[1],ilog(look->quant_q-1)); 857 858 859 /* partition by partition */ 860 for(i=0,j=2;i<info->partitions;i++){ 861 int class=info->partitionclass[i]; 862 int cdim=info->class_dim[class]; 863 int csubbits=info->class_subs[class]; 864 int csub=1<<csubbits; 865 int bookas[8]={0,0,0,0,0,0,0,0}; 866 int cval=0; 867 int cshift=0; 868 int k,l; 869 870 /* generate the partition's first stage cascade value */ 871 if(csubbits){ 872 int maxval[8]; 873 for(k=0;k<csub;k++){ 874 int booknum=info->class_subbook[class][k]; 875 if(booknum<0){ 876 maxval[k]=1; 877 }else{ 878 maxval[k]=sbooks[info->class_subbook[class][k]]->entries; 879 } 880 } 881 for(k=0;k<cdim;k++){ 882 for(l=0;l<csub;l++){ 883 int val=out[j+k]; 884 if(val<maxval[l]){ 885 bookas[k]=l; 886 break; 887 } 888 } 889 cval|= bookas[k]<<cshift; 890 cshift+=csubbits; 891 } 892 /* write it */ 893 look->phrasebits+= 894 vorbis_book_encode(books+info->class_book[class],cval,opb); 895 896 #ifdef TRAIN_FLOOR1 897 { 898 FILE *of; 899 char buffer[80]; 900 sprintf(buffer,"line_%dx%ld_class%d.vqd", 901 vb->pcmend/2,posts-2,class); 902 of=fopen(buffer,"a"); 903 fprintf(of,"%d\n",cval); 904 fclose(of); 905 } 906 #endif 907 } 908 909 /* write post values */ 910 for(k=0;k<cdim;k++){ 911 int book=info->class_subbook[class][bookas[k]]; 912 if(book>=0){ 913 /* hack to allow training with 'bad' books */ 914 if(out[j+k]<(books+book)->entries) 915 look->postbits+=vorbis_book_encode(books+book, 916 out[j+k],opb); 917 /*else 918 fprintf(stderr,"+!");*/ 919 920 #ifdef TRAIN_FLOOR1 921 { 922 FILE *of; 923 char buffer[80]; 924 sprintf(buffer,"line_%dx%ld_%dsub%d.vqd", 925 vb->pcmend/2,posts-2,class,bookas[k]); 926 of=fopen(buffer,"a"); 927 fprintf(of,"%d\n",out[j+k]); 928 fclose(of); 929 } 930 #endif 931 } 932 } 933 j+=cdim; 934 } 935 936 { 937 /* generate quantized floor equivalent to what we'd unpack in decode */ 938 /* render the lines */ 939 int hx=0; 940 int lx=0; 941 int ly=post[0]*info->mult; 942 int n=ci->blocksizes[vb->W]/2; 943 944 for(j=1;j<look->posts;j++){ 945 int current=look->forward_index[j]; 946 int hy=post[current]&0x7fff; 947 if(hy==post[current]){ 948 949 hy*=info->mult; 950 hx=info->postlist[current]; 951 952 render_line0(n,lx,hx,ly,hy,ilogmask); 953 954 lx=hx; 955 ly=hy; 956 } 957 } 958 for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */ 959 return(1); 960 } 961 }else{ 962 oggpack_write(opb,0,1); 963 memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask)); 964 return(0); 965 } 966 } 967 968 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){ 969 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in; 970 vorbis_info_floor1 *info=look->vi; 971 codec_setup_info *ci=vb->vd->vi->codec_setup; 972 973 int i,j,k; 974 codebook *books=ci->fullbooks; 975 976 /* unpack wrapped/predicted values from stream */ 977 if(oggpack_read(&vb->opb,1)==1){ 978 int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value)); 979 980 fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); 981 fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1)); 982 983 /* partition by partition */ 984 for(i=0,j=2;i<info->partitions;i++){ 985 int class=info->partitionclass[i]; 986 int cdim=info->class_dim[class]; 987 int csubbits=info->class_subs[class]; 988 int csub=1<<csubbits; 989 int cval=0; 990 991 /* decode the partition's first stage cascade value */ 992 if(csubbits){ 993 cval=vorbis_book_decode(books+info->class_book[class],&vb->opb); 994 995 if(cval==-1)goto eop; 996 } 997 998 for(k=0;k<cdim;k++){ 999 int book=info->class_subbook[class][cval&(csub-1)]; 1000 cval>>=csubbits; 1001 if(book>=0){ 1002 if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1) 1003 goto eop; 1004 }else{ 1005 fit_value[j+k]=0; 1006 } 1007 } 1008 j+=cdim; 1009 } 1010 1011 /* unwrap positive values and reconsitute via linear interpolation */ 1012 for(i=2;i<look->posts;i++){ 1013 int predicted=render_point(info->postlist[look->loneighbor[i-2]], 1014 info->postlist[look->hineighbor[i-2]], 1015 fit_value[look->loneighbor[i-2]], 1016 fit_value[look->hineighbor[i-2]], 1017 info->postlist[i]); 1018 int hiroom=look->quant_q-predicted; 1019 int loroom=predicted; 1020 int room=(hiroom<loroom?hiroom:loroom)<<1; 1021 int val=fit_value[i]; 1022 1023 if(val){ 1024 if(val>=room){ 1025 if(hiroom>loroom){ 1026 val = val-loroom; 1027 }else{ 1028 val = -1-(val-hiroom); 1029 } 1030 }else{ 1031 if(val&1){ 1032 val= -((val+1)>>1); 1033 }else{ 1034 val>>=1; 1035 } 1036 } 1037 1038 fit_value[i]=val+predicted; 1039 fit_value[look->loneighbor[i-2]]&=0x7fff; 1040 fit_value[look->hineighbor[i-2]]&=0x7fff; 1041 1042 }else{ 1043 fit_value[i]=predicted|0x8000; 1044 } 1045 1046 } 1047 1048 return(fit_value); 1049 } 1050 eop: 1051 return(NULL); 1052 } 1053 1054 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo, 1055 float *out){ 1056 vorbis_look_floor1 *look=(vorbis_look_floor1 *)in; 1057 vorbis_info_floor1 *info=look->vi; 1058 1059 codec_setup_info *ci=vb->vd->vi->codec_setup; 1060 int n=ci->blocksizes[vb->W]/2; 1061 int j; 1062 1063 if(memo){ 1064 /* render the lines */ 1065 int *fit_value=(int *)memo; 1066 int hx=0; 1067 int lx=0; 1068 int ly=fit_value[0]*info->mult; 1069 for(j=1;j<look->posts;j++){ 1070 int current=look->forward_index[j]; 1071 int hy=fit_value[current]&0x7fff; 1072 if(hy==fit_value[current]){ 1073 1074 hy*=info->mult; 1075 hx=info->postlist[current]; 1076 1077 render_line(n,lx,hx,ly,hy,out); 1078 1079 lx=hx; 1080 ly=hy; 1081 } 1082 } 1083 for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */ 1084 return(1); 1085 } 1086 memset(out,0,sizeof(*out)*n); 1087 return(0); 1088 } 1089 1090 /* export hooks */ 1091 const vorbis_func_floor floor1_exportbundle={ 1092 &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info, 1093 &floor1_free_look,&floor1_inverse1,&floor1_inverse2 1094 }; 1095