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}