001/* JOrbis 002 * Copyright (C) 2000 ymnk, JCraft,Inc. 003 * 004 * Written by: 2000 ymnk<ymnk@jcaft.com> 005 * 006 * Many thanks to 007 * Monty <monty@xiph.org> and 008 * The XIPHOPHORUS Company http://www.xiph.org/ . 009 * JOrbis has been based on their awesome works, Vorbis codec. 010 * 011 * This program is free software; you can redistribute it and/or 012 * modify it under the terms of the GNU Library General Public License 013 * as published by the Free Software Foundation; either version 2 of 014 * the License, or (at your option) any later version. 015 016 * This program is distributed in the hope that it will be useful, 017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 019 * GNU Library General Public License for more details. 020 * 021 * You should have received a copy of the GNU Library General Public 022 * License along with this program; if not, write to the Free Software 023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 024 */ 025 026package com.jcraft.jorbis; 027 028import com.jcraft.jogg.*; 029 030class Floor1 extends FuncFloor{ 031 static final int floor1_rangedb=140; 032 static final int VIF_POSIT=63; 033 034 void pack(Object i, Buffer opb){ 035 InfoFloor1 info=(InfoFloor1)i; 036 037 int count=0; 038 int rangebits; 039 int maxposit=info.postlist[1]; 040 int maxclass=-1; 041 042 /* save out partitions */ 043 opb.write(info.partitions,5); /* only 0 to 31 legal */ 044 for(int j=0;j<info.partitions;j++){ 045 opb.write(info.partitionclass[j],4); /* only 0 to 15 legal */ 046 if(maxclass<info.partitionclass[j]) 047 maxclass=info.partitionclass[j]; 048 } 049 050 /* save out partition classes */ 051 for(int j=0;j<maxclass+1;j++){ 052 opb.write(info.class_dim[j]-1,3); /* 1 to 8 */ 053 opb.write(info.class_subs[j],2); /* 0 to 3 */ 054 if(info.class_subs[j]!=0){ 055 opb.write(info.class_book[j],8); 056 } 057 for(int k=0;k<(1<<info.class_subs[j]);k++){ 058 opb.write(info.class_subbook[j][k]+1,8); 059 } 060 } 061 062 /* save out the post list */ 063 opb.write(info.mult-1,2); /* only 1,2,3,4 legal now */ 064 opb.write(ilog2(maxposit),4); 065 rangebits=ilog2(maxposit); 066 067 for(int j=0,k=0;j<info.partitions;j++){ 068 count+=info.class_dim[info.partitionclass[j]]; 069 for(;k<count;k++){ 070 opb.write(info.postlist[k+2],rangebits); 071 } 072 } 073 } 074 075 Object unpack(Info vi , Buffer opb){ 076 int count=0,maxclass=-1,rangebits; 077 InfoFloor1 info=new InfoFloor1(); 078 079 /* read partitions */ 080 info.partitions=opb.read(5); /* only 0 to 31 legal */ 081 for(int j=0;j<info.partitions;j++){ 082 info.partitionclass[j]=opb.read(4); /* only 0 to 15 legal */ 083 if(maxclass<info.partitionclass[j]) 084 maxclass=info.partitionclass[j]; 085 } 086 087 /* read partition classes */ 088 for(int j=0;j<maxclass+1;j++){ 089 info.class_dim[j]=opb.read(3)+1; /* 1 to 8 */ 090 info.class_subs[j]=opb.read(2); /* 0,1,2,3 bits */ 091 if(info.class_subs[j]<0){ 092 //goto err_out; 093 info.free(); 094 return(null); 095 } 096 if(info.class_subs[j]!=0){ 097 info.class_book[j]=opb.read(8); 098 } 099 if(info.class_book[j]<0 || info.class_book[j]>=vi.books){ 100 //goto err_out; 101 info.free(); 102 return(null); 103 } 104 for(int k=0;k<(1<<info.class_subs[j]);k++){ 105 info.class_subbook[j][k]=opb.read(8)-1; 106 if(info.class_subbook[j][k]<-1 || info.class_subbook[j][k]>=vi.books){ 107 //goto err_out; 108 info.free(); 109 return(null); 110 } 111 } 112 } 113 114 /* read the post list */ 115 info.mult=opb.read(2)+1; /* only 1,2,3,4 legal now */ 116 rangebits=opb.read(4); 117 118 for(int j=0,k=0;j<info.partitions;j++){ 119 count+=info.class_dim[info.partitionclass[j]]; 120 for(;k<count;k++){ 121 int t=info.postlist[k+2]=opb.read(rangebits); 122 if(t<0 || t>=(1<<rangebits)){ 123 //goto err_out; 124 info.free(); 125 return(null); 126 } 127 } 128 } 129 info.postlist[0]=0; 130 info.postlist[1]=1<<rangebits; 131 132 return(info); 133// err_out: 134// info.free(); 135// return(null); 136 } 137 138 Object look(DspState vd, InfoMode mi, Object i){ 139 int _n=0; 140 141 int[] sortpointer=new int[VIF_POSIT+2]; 142 143// Info vi=vd.vi; 144 145 InfoFloor1 info=(InfoFloor1)i; 146 LookFloor1 look=new LookFloor1(); 147 look.vi=info; 148 look.n=info.postlist[1]; 149 150 /* we drop each position value in-between already decoded values, 151 and use linear interpolation to predict each new value past the 152 edges. The positions are read in the order of the position 153 list... we precompute the bounding positions in the lookup. Of 154 course, the neighbors can change (if a position is declined), but 155 this is an initial mapping */ 156 157 for(int j=0;j<info.partitions;j++){ 158 _n+=info.class_dim[info.partitionclass[j]]; 159 } 160 _n+=2; 161 look.posts=_n; 162 163 /* also store a sorted position index */ 164 for(int j=0;j<_n;j++){ 165 sortpointer[j]=j; 166 } 167// qsort(sortpointer,n,sizeof(int),icomp); // !! 168 169 int foo; 170 for(int j=0; j<_n-1; j++){ 171 for(int k=j; k<_n; k++){ 172 if(info.postlist[sortpointer[j]]>info.postlist[sortpointer[k]]){ 173 foo=sortpointer[k]; 174 sortpointer[k]=sortpointer[j]; 175 sortpointer[j]=foo; 176 } 177 } 178 } 179 180 /* points from sort order back to range number */ 181 for(int j=0;j<_n;j++){ 182 look.forward_index[j]=sortpointer[j]; 183 } 184 /* points from range order to sorted position */ 185 for(int j=0;j<_n;j++){ 186 look.reverse_index[look.forward_index[j]]=j; 187 } 188 /* we actually need the post values too */ 189 for(int j=0;j<_n;j++){ 190 look.sorted_index[j]=info.postlist[look.forward_index[j]]; 191 } 192 193 194 /* quantize values to multiplier spec */ 195 switch(info.mult){ 196 case 1: /* 1024 -> 256 */ 197 look.quant_q=256; 198 break; 199 case 2: /* 1024 -> 128 */ 200 look.quant_q=128; 201 break; 202 case 3: /* 1024 -> 86 */ 203 look.quant_q=86; 204 break; 205 case 4: /* 1024 -> 64 */ 206 look.quant_q=64; 207 break; 208 default: 209 look.quant_q=-1; 210 } 211 212 /* discover our neighbors for decode where we don't use fit flags 213 (that would push the neighbors outward) */ 214 for(int j=0;j<_n-2;j++){ 215 int lo=0; 216 int hi=1; 217 int lx=0; 218 int hx=look.n; 219 int currentx=info.postlist[j+2]; 220 for(int k=0;k<j+2;k++){ 221 int x=info.postlist[k]; 222 if(x>lx && x<currentx){ 223 lo=k; 224 lx=x; 225 } 226 if(x<hx && x>currentx){ 227 hi=k; 228 hx=x; 229 } 230 } 231 look.loneighbor[j]=lo; 232 look.hineighbor[j]=hi; 233 } 234 235 return look; 236 } 237 238 void free_info(Object i){} 239 void free_look(Object i){} 240 void free_state(Object vs){} 241 242 int forward(Block vb, Object i, float[] in, float[] out, Object vs){return 0;} 243 244 Object inverse1(Block vb, Object ii, Object memo){ 245 //System.err.println("Floor1.inverse "+i.getClass()+"]"); 246 LookFloor1 look=(LookFloor1)ii; 247 InfoFloor1 info=look.vi; 248 CodeBook[] books=vb.vd.fullbooks; 249 250 /* unpack wrapped/predicted values from stream */ 251 if(vb.opb.read(1)==1){ 252 int[] fit_value=null; 253 if(memo instanceof int[]){ 254 fit_value=(int[])memo; 255 } 256 if(fit_value==null || fit_value.length<look.posts){ 257 fit_value=new int[look.posts]; 258 } 259 else{ 260 for(int i=0; i<fit_value.length; i++) fit_value[i]=0; 261 } 262 263 fit_value[0]=vb.opb.read(ilog(look.quant_q-1)); 264 fit_value[1]=vb.opb.read(ilog(look.quant_q-1)); 265 266 /* partition by partition */ 267 for(int i=0,j=2;i<info.partitions;i++){ 268 int clss=info.partitionclass[i]; 269 int cdim=info.class_dim[clss]; 270 int csubbits=info.class_subs[clss]; 271 int csub=1<<csubbits; 272 int cval=0; 273 274 /* decode the partition's first stage cascade value */ 275 if(csubbits!=0){ 276 cval=books[info.class_book[clss]].decode(vb.opb); 277 278 if(cval==-1){ 279 //goto eop; 280 return(null); 281 } 282 } 283 284 for(int k=0;k<cdim;k++){ 285 int book=info.class_subbook[clss][cval&(csub-1)]; 286 cval>>>=csubbits; 287 if(book>=0){ 288 if((fit_value[j+k]=books[book].decode(vb.opb))==-1){ 289 //goto eop; 290 return(null); 291 } 292 } 293 else{ 294 fit_value[j+k]=0; 295 } 296 } 297 j+=cdim; 298 } 299 300 /* unwrap positive values and reconsitute via linear interpolation */ 301 for(int i=2;i<look.posts;i++){ 302 int predicted=render_point(info.postlist[look.loneighbor[i-2]], 303 info.postlist[look.hineighbor[i-2]], 304 fit_value[look.loneighbor[i-2]], 305 fit_value[look.hineighbor[i-2]], 306 info.postlist[i]); 307 int hiroom=look.quant_q-predicted; 308 int loroom=predicted; 309 int room=(hiroom<loroom?hiroom:loroom)<<1; 310 int val=fit_value[i]; 311 312 if(val!=0){ 313 if(val>=room){ 314 if(hiroom>loroom){ 315 val = val-loroom; 316 } 317 else{ 318 val = -1-(val-hiroom); 319 } 320 } 321 else{ 322 if((val&1)!=0){ 323 val= -((val+1)>>>1); 324 } 325 else{ 326 val>>=1; 327 } 328 } 329 330 fit_value[i]=val+predicted; 331 fit_value[look.loneighbor[i-2]]&=0x7fff; 332 fit_value[look.hineighbor[i-2]]&=0x7fff; 333 } 334 else{ 335 fit_value[i]=predicted|0x8000; 336 } 337 } 338 return(fit_value); 339 } 340 341// eop: 342// return(NULL); 343 return(null); 344 } 345 346 private static int render_point(int x0,int x1,int y0,int y1,int x){ 347 y0&=0x7fff; /* mask off flag */ 348 y1&=0x7fff; 349 350 { 351 int dy=y1-y0; 352 int adx=x1-x0; 353 int ady=Math.abs(dy); 354 int err=ady*(x-x0); 355 356 int off=(int)(err/adx); 357 if(dy<0)return(y0-off); 358 return(y0+off); 359 } 360 } 361 362 int inverse2(Block vb, Object i, Object memo, float[] out){ 363 LookFloor1 look=(LookFloor1)i; 364 InfoFloor1 info=look.vi; 365 int n=vb.vd.vi.blocksizes[vb.mode]/2; 366 367 if(memo!=null){ 368 /* render the lines */ 369 int[] fit_value=(int[] )memo; 370 int hx=0; 371 int lx=0; 372 int ly=fit_value[0]*info.mult; 373 for(int j=1;j<look.posts;j++){ 374 int current=look.forward_index[j]; 375 int hy=fit_value[current]&0x7fff; 376 if(hy==fit_value[current]){ 377 hy*=info.mult; 378 hx=info.postlist[current]; 379 380 render_line(lx,hx,ly,hy,out); 381 382 lx=hx; 383 ly=hy; 384 } 385 } 386 for(int j=hx;j<n;j++){ 387 out[j]*=out[j-1]; /* be certain */ 388 } 389 return(1); 390 } 391 for(int j=0; j<n; j++){ 392 out[j]=0.f; 393 } 394 return(0); 395 } 396 397 398 private static float[] FLOOR_fromdB_LOOKUP={ 399 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, 400 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, 401 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, 402 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, 403 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, 404 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, 405 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, 406 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, 407 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, 408 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, 409 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, 410 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, 411 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, 412 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, 413 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, 414 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, 415 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, 416 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, 417 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, 418 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, 419 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, 420 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, 421 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, 422 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, 423 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, 424 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, 425 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, 426 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, 427 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, 428 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, 429 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, 430 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, 431 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, 432 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, 433 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, 434 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, 435 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, 436 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, 437 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, 438 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, 439 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, 440 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, 441 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, 442 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, 443 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, 444 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, 445 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, 446 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, 447 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, 448 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, 449 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, 450 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, 451 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, 452 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, 453 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, 454 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, 455 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, 456 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, 457 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, 458 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, 459 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, 460 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, 461 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, 462 0.82788260F, 0.88168307F, 0.9389798F, 1.F 463 }; 464 465 private static void render_line(int x0, int x1,int y0,int y1,float[] d){ 466 int dy=y1-y0; 467 int adx=x1-x0; 468 int ady=Math.abs(dy); 469 int base=dy/adx; 470 int sy=(dy<0?base-1:base+1); 471 int x=x0; 472 int y=y0; 473 int err=0; 474 475 ady-=Math.abs(base*adx); 476 477 d[x]*=FLOOR_fromdB_LOOKUP[y]; 478 while(++x<x1){ 479 err=err+ady; 480 if(err>=adx){ 481 err-=adx; 482 y+=sy; 483 } 484 else{ 485 y+=base; 486 } 487 d[x]*=FLOOR_fromdB_LOOKUP[y]; 488 } 489 } 490 491 static int ilog(int v){ 492 int ret=0; 493 while(v!=0){ 494 ret++; 495 v>>>=1; 496 } 497 return(ret); 498 } 499 500 private static int ilog2(int v){ 501 int ret=0; 502 while(v>1){ 503 ret++; 504 v>>>=1; 505 } 506 return(ret); 507 } 508} 509 510class InfoFloor1{ 511 static final int VIF_POSIT=63; 512 static final int VIF_CLASS=16; 513 static final int VIF_PARTS=31; 514 515 int partitions; /* 0 to 31 */ 516 int[] partitionclass=new int[VIF_PARTS]; /* 0 to 15 */ 517 518 int[] class_dim=new int[VIF_CLASS]; /* 1 to 8 */ 519 int[] class_subs=new int[VIF_CLASS]; /* 0,1,2,3 (bits: 1<<n poss) */ 520 int[] class_book=new int[VIF_CLASS]; /* subs ^ dim entries */ 521 int[][] class_subbook=new int[VIF_CLASS][]; /* [VIF_CLASS][subs] */ 522 523 524 int mult; /* 1 2 3 or 4 */ 525 int[] postlist=new int[VIF_POSIT+2]; /* first two implicit */ 526 527 528 /* encode side analysis parameters */ 529 float maxover; 530 float maxunder; 531 float maxerr; 532 533 int twofitminsize; 534 int twofitminused; 535 int twofitweight; 536 float twofitatten; 537 int unusedminsize; 538 int unusedmin_n; 539 540 int n; 541 542 InfoFloor1(){ 543 for(int i=0; i<class_subbook.length; i++){ 544 class_subbook[i]=new int[8]; 545 } 546 } 547 548 void free(){ 549 partitionclass=null; 550 class_dim=null; 551 class_subs=null; 552 class_book=null; 553 class_subbook=null; 554 postlist=null; 555 } 556 557 Object copy_info(){ 558 InfoFloor1 info=this; 559 InfoFloor1 ret=new InfoFloor1(); 560 561 ret.partitions=info.partitions; 562 System.arraycopy(info.partitionclass, 0, ret.partitionclass, 0, VIF_PARTS); 563 System.arraycopy(info.class_dim, 0, ret.class_dim, 0, VIF_CLASS); 564 System.arraycopy(info.class_subs, 0, ret.class_subs, 0, VIF_CLASS); 565 System.arraycopy(info.class_book, 0, ret.class_book, 0, VIF_CLASS); 566 567 for(int j=0; j<VIF_CLASS; j++){ 568 System.arraycopy(info.class_subbook[j], 0, 569 ret.class_subbook[j], 0, 8); 570 } 571 572 ret.mult=info.mult; 573 System.arraycopy(info.postlist, 0, ret.postlist, 0, VIF_POSIT+2); 574 575 ret.maxover=info.maxover; 576 ret.maxunder=info.maxunder; 577 ret.maxerr=info.maxerr; 578 579 ret.twofitminsize=info.twofitminsize; 580 ret.twofitminused=info.twofitminused; 581 ret.twofitweight=info.twofitweight; 582 ret.twofitatten=info.twofitatten; 583 ret.unusedminsize=info.unusedminsize; 584 ret.unusedmin_n=info.unusedmin_n; 585 586 ret.n=info.n; 587 588 return(ret); 589 } 590 591} 592 593class LookFloor1{ 594 static final int VIF_POSIT=63; 595 596 int[] sorted_index=new int[VIF_POSIT+2]; 597 int[] forward_index=new int[VIF_POSIT+2]; 598 int[] reverse_index=new int[VIF_POSIT+2]; 599 int[] hineighbor=new int[VIF_POSIT]; 600 int[] loneighbor=new int[VIF_POSIT]; 601 int posts; 602 603 int n; 604 int quant_q; 605 InfoFloor1 vi; 606 607 int phrasebits; 608 int postbits; 609 int frames; 610 611 void free(){ 612 613/* 614 System.out.println("floor 1 bit usage "+ 615 (float)(phrasebits/frames) 616 +":"+ 617 (float)(postbits/frames) 618 +"("+ 619 (float)((postbits+phrasebits)/frames) 620 +" total)" 621 622*/ 623 624 sorted_index=null; 625 forward_index=null; 626 reverse_index=null; 627 hineighbor=null; 628 loneighbor=null; 629 } 630} 631 632class Lsfit_acc{ 633 long x0; 634 long x1; 635 636 long xa; 637 long ya; 638 long x2a; 639 long y2a; 640 long xya; 641 long n; 642 long an; 643 long un; 644 long edgey0; 645 long edgey1; 646} 647 648class EchstateFloor1{ 649 int[] codewords; 650 float[] curve; 651 long frameno; 652 long codes; 653}