]> Joshua Wise's Git repositories - patchfork.git/blob - jorbis/src/com/jcraft/jorbis/Floor1.java
initial import from pitchfork-0.5.5
[patchfork.git] / jorbis / src / com / jcraft / jorbis / Floor1.java
1 /* JOrbis
2  * Copyright (C) 2000 ymnk, JCraft,Inc.
3  *  
4  * Written by: 2000 ymnk<ymnk@jcraft.com>
5  *   
6  * Many thanks to 
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.
10  *   
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.
15    
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.
20  * 
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.
24  */
25
26 package com.jcraft.jorbis;
27
28 import com.jcraft.jogg.*;
29
30 class Floor1 extends FuncFloor{
31   static final int floor1_rangedb=140;
32   static final int VIF_POSIT=63;
33
34   void pack(Object i, Buffer opb){
35     InfoFloor1 info=(InfoFloor1)i;
36
37     int count=0;
38     int rangebits;
39     int maxposit=info.postlist[1];
40     int maxclass=-1;
41
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];
48     }
49
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);
56       }
57       for(int k=0;k<(1<<info.class_subs[j]);k++){
58         opb.write(info.class_subbook[j][k]+1,8);
59       }
60     }
61
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);
66
67     for(int j=0,k=0;j<info.partitions;j++){
68       count+=info.class_dim[info.partitionclass[j]];
69       for(;k<count;k++){
70         opb.write(info.postlist[k+2],rangebits);
71       }
72     }
73   }
74
75   Object unpack(Info vi , Buffer opb){
76     int count=0,maxclass=-1,rangebits;
77     InfoFloor1 info=new InfoFloor1();
78
79     /* read partitions */
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];
85     }
86
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){
92         //goto err_out;
93         info.free();
94         return(null);
95       }
96       if(info.class_subs[j]!=0){
97         info.class_book[j]=opb.read(8);
98       }
99       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
510 class 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
593 class 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
632 class 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
648 class EchstateFloor1{
649   int[] codewords;
650   float[] curve;
651   long frameno;
652   long codes;
653 }
This page took 0.056695 seconds and 4 git commands to generate.