2 * Copyright (C) 2000 ymnk, JCraft,Inc.
4 * Written by: 2000 ymnk<ymnk@jcraft.com>
7 * Monty <monty@xiph.org> and
8 * The XIPHOPHORUS Company http://www.xiph.org/ .
9 * JOrbis has been based on their awesome works, Vorbis codec.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public License
13 * as published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
21 * You should have received a copy of the GNU Library General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 package com.jcraft.jorbis;
28 import com.jcraft.jogg.*;
30 class Floor1 extends FuncFloor{
31 static final int floor1_rangedb=140;
32 static final int VIF_POSIT=63;
34 void pack(Object i, Buffer opb){
35 InfoFloor1 info=(InfoFloor1)i;
39 int maxposit=info.postlist[1];
42 /* save out partitions */
43 opb.write(info.partitions,5); /* only 0 to 31 legal */
44 for(int j=0;j<info.partitions;j++){
45 opb.write(info.partitionclass[j],4); /* only 0 to 15 legal */
46 if(maxclass<info.partitionclass[j])
47 maxclass=info.partitionclass[j];
50 /* save out partition classes */
51 for(int j=0;j<maxclass+1;j++){
52 opb.write(info.class_dim[j]-1,3); /* 1 to 8 */
53 opb.write(info.class_subs[j],2); /* 0 to 3 */
54 if(info.class_subs[j]!=0){
55 opb.write(info.class_book[j],8);
57 for(int k=0;k<(1<<info.class_subs[j]);k++){
58 opb.write(info.class_subbook[j][k]+1,8);
62 /* save out the post list */
63 opb.write(info.mult-1,2); /* only 1,2,3,4 legal now */
64 opb.write(ilog2(maxposit),4);
65 rangebits=ilog2(maxposit);
67 for(int j=0,k=0;j<info.partitions;j++){
68 count+=info.class_dim[info.partitionclass[j]];
70 opb.write(info.postlist[k+2],rangebits);
75 Object unpack(Info vi , Buffer opb){
76 int count=0,maxclass=-1,rangebits;
77 InfoFloor1 info=new InfoFloor1();
80 info.partitions=opb.read(5); /* only 0 to 31 legal */
81 for(int j=0;j<info.partitions;j++){
82 info.partitionclass[j]=opb.read(4); /* only 0 to 15 legal */
83 if(maxclass<info.partitionclass[j])
84 maxclass=info.partitionclass[j];
87 /* read partition classes */
88 for(int j=0;j<maxclass+1;j++){
89 info.class_dim[j]=opb.read(3)+1; /* 1 to 8 */
90 info.class_subs[j]=opb.read(2); /* 0,1,2,3 bits */
91 if(info.class_subs[j]<0){
96 if(info.class_subs[j]!=0){
97 info.class_book[j]=opb.read(8);
99 if(info.class_book[j]<0 || info.class_book[j]>=vi.books){
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){
114 /* read the post list */
115 info.mult=opb.read(2)+1; /* only 1,2,3,4 legal now */
116 rangebits=opb.read(4);
118 for(int j=0,k=0;j<info.partitions;j++){
119 count+=info.class_dim[info.partitionclass[j]];
121 int t=info.postlist[k+2]=opb.read(rangebits);
122 if(t<0 || t>=(1<<rangebits)){
130 info.postlist[1]=1<<rangebits;
138 Object look(DspState vd, InfoMode mi, Object i){
141 int[] sortpointer=new int[VIF_POSIT+2];
145 InfoFloor1 info=(InfoFloor1)i;
146 LookFloor1 look=new LookFloor1();
148 look.n=info.postlist[1];
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 */
157 for(int j=0;j<info.partitions;j++){
158 _n+=info.class_dim[info.partitionclass[j]];
163 /* also store a sorted position index */
164 for(int j=0;j<_n;j++){
167 // qsort(sortpointer,n,sizeof(int),icomp); // !!
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]]){
174 sortpointer[k]=sortpointer[j];
180 /* points from sort order back to range number */
181 for(int j=0;j<_n;j++){
182 look.forward_index[j]=sortpointer[j];
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;
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]];
194 /* quantize values to multiplier spec */
196 case 1: /* 1024 -> 256 */
199 case 2: /* 1024 -> 128 */
202 case 3: /* 1024 -> 86 */
205 case 4: /* 1024 -> 64 */
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++){
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){
226 if(x<hx && x>currentx){
231 look.loneighbor[j]=lo;
232 look.hineighbor[j]=hi;
238 void free_info(Object i){}
239 void free_look(Object i){}
240 void free_state(Object vs){}
242 int forward(Block vb, Object i, float[] in, float[] out, Object vs){return 0;}
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;
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;
256 if(fit_value==null || fit_value.length<look.posts){
257 fit_value=new int[look.posts];
260 for(int i=0; i<fit_value.length; i++) fit_value[i]=0;
263 fit_value[0]=vb.opb.read(ilog(look.quant_q-1));
264 fit_value[1]=vb.opb.read(ilog(look.quant_q-1));
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;
274 /* decode the partition's first stage cascade value */
276 cval=books[info.class_book[clss]].decode(vb.opb);
284 for(int k=0;k<cdim;k++){
285 int book=info.class_subbook[clss][cval&(csub-1)];
288 if((fit_value[j+k]=books[book].decode(vb.opb))==-1){
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]],
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];
318 val = -1-(val-hiroom);
330 fit_value[i]=val+predicted;
331 fit_value[look.loneighbor[i-2]]&=0x7fff;
332 fit_value[look.hineighbor[i-2]]&=0x7fff;
335 fit_value[i]=predicted|0x8000;
346 private static int render_point(int x0,int x1,int y0,int y1,int x){
347 y0&=0x7fff; /* mask off flag */
353 int ady=Math.abs(dy);
356 int off=(int)(err/adx);
357 if(dy<0)return(y0-off);
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;
368 /* render the lines */
369 int[] fit_value=(int[] )memo;
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]){
378 hx=info.postlist[current];
380 render_line(lx,hx,ly,hy,out);
386 for(int j=hx;j<n;j++){
387 out[j]*=out[j-1]; /* be certain */
391 for(int j=0; j<n; j++){
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
465 private static void render_line(int x0, int x1,int y0,int y1,float[] d){
468 int ady=Math.abs(dy);
470 int sy=(dy<0?base-1:base+1);
475 ady-=Math.abs(base*adx);
477 d[x]*=FLOOR_fromdB_LOOKUP[y];
487 d[x]*=FLOOR_fromdB_LOOKUP[y];
491 static int ilog(int v){
500 private static int ilog2(int v){
511 static final int VIF_POSIT=63;
512 static final int VIF_CLASS=16;
513 static final int VIF_PARTS=31;
515 int partitions; /* 0 to 31 */
516 int[] partitionclass=new int[VIF_PARTS]; /* 0 to 15 */
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] */
524 int mult; /* 1 2 3 or 4 */
525 int[] postlist=new int[VIF_POSIT+2]; /* first two implicit */
528 /* encode side analysis parameters */
543 for(int i=0; i<class_subbook.length; i++){
544 class_subbook[i]=new int[8];
558 InfoFloor1 info=this;
559 InfoFloor1 ret=new InfoFloor1();
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);
567 for(int j=0; j<VIF_CLASS; j++){
568 System.arraycopy(info.class_subbook[j], 0,
569 ret.class_subbook[j], 0, 8);
573 System.arraycopy(info.postlist, 0, ret.postlist, 0, VIF_POSIT+2);
575 ret.maxover=info.maxover;
576 ret.maxunder=info.maxunder;
577 ret.maxerr=info.maxerr;
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;
594 static final int VIF_POSIT=63;
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];
614 System.out.println("floor 1 bit usage "+
615 (float)(phrasebits/frames)
617 (float)(postbits/frames)
619 (float)((postbits+phrasebits)/frames)
648 class EchstateFloor1{