/* csvorbis * Copyright (C) 2000 ymnk, JCraft,Inc. * * Written by: 2000 ymnk * Ported to C# from JOrbis by: Mark Crichton * * Thanks go to the JOrbis team, for licencing the code under the * LGPL, making my job a lot easier. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ using System; using csogg; namespace csvorbis { class Floor1 : FuncFloor { //static int floor1_rangedb=140; static int VIF_POSIT=63; override public void pack(Object i, csBuffer opb) { InfoFloor1 info=(InfoFloor1)i; int count=0; int rangebits; int maxposit=info.postlist[1]; int maxclass=-1; /* save out partitions */ opb.write(info.partitions,5); /* only 0 to 31 legal */ for(int j=0;j=vi.books) { //goto err_out; info.free(); return(null); } for(int k=0;k<(1<=vi.books) { //goto err_out; info.free(); return(null); } } } /* read the post list */ info.mult=opb.read(2)+1; /* only 1,2,3,4 legal now */ rangebits=opb.read(4); for(int j=0,k=0;j=(1<info.postlist[sortpointer[k]]) { foo=sortpointer[k]; sortpointer[k]=sortpointer[j]; sortpointer[j]=foo; } } } /* points from sort order back to range number */ for(int j=0;j<_n;j++) { look.forward_index[j]=sortpointer[j]; } /* points from range order to sorted position */ for(int j=0;j<_n;j++) { look.reverse_index[look.forward_index[j]]=j; } /* we actually need the post values too */ for(int j=0;j<_n;j++) { look.sorted_index[j]=info.postlist[look.forward_index[j]]; } /* quantize values to multiplier spec */ switch(info.mult) { case 1: /* 1024 -> 256 */ look.quant_q=256; break; case 2: /* 1024 -> 128 */ look.quant_q=128; break; case 3: /* 1024 -> 86 */ look.quant_q=86; break; case 4: /* 1024 -> 64 */ look.quant_q=64; break; default: look.quant_q=-1; break; } /* discover our neighbors for decode where we don't use fit flags (that would push the neighbors outward) */ for(int j=0;j<_n-2;j++) { int lo=0; int hi=1; int lx=0; int hx=look.n; int currentx=info.postlist[j+2]; for(int k=0;klx && xcurrentx) { hi=k; hx=x; } } look.loneighbor[j]=lo; look.hineighbor[j]=hi; } return look; } override public void free_info(Object i){} override public void free_look(Object i){} override public void free_state(Object vs){} override public int forward(Block vb, Object i, float[] fin, float[] fout, Object vs){return 0;} override public Object inverse1(Block vb, Object ii, Object memo) { LookFloor1 look=(LookFloor1)ii; InfoFloor1 info=look.vi; CodeBook[] books=vb.vd.fullbooks; /* unpack wrapped/predicted values from stream */ if(vb.opb.read(1)==1) { int[] fit_value=null; if(memo is int[]) { fit_value=(int[])memo; } if(fit_value==null || fit_value.Length> csubbits); if(book>=0) { if((fit_value[j+k]=books[book].decode(vb.opb))==-1) { return(null); } } else { fit_value[j+k]=0; } } j+=cdim; } /* unwrap positive values and reconsitute via linear interpolation */ for(int i=2;i=room) { if(hiroom>loroom) { val = val-loroom; } else { val = -1-(val-hiroom); } } else { if((val&1)!=0) { val= (int)(-((uint)(val+1) >> 1)); } else { val>>=1; } } fit_value[i]=val+predicted; fit_value[look.loneighbor[i-2]]&=0x7fff; fit_value[look.hineighbor[i-2]]&=0x7fff; } else { fit_value[i]=predicted|0x8000; } } return(fit_value); } // eop: // return(NULL); return(null); } private static int render_point(int x0,int x1,int y0,int y1,int x) { y0&=0x7fff; /* mask off flag */ y1&=0x7fff; { int dy=y1-y0; int adx=x1-x0; int ady=Math.Abs(dy); int err=ady*(x-x0); int off=(int)(err/adx); if(dy<0)return(y0-off); return(y0+off); } } override public int inverse2(Block vb, Object i, Object memo, float[] fout) { LookFloor1 look=(LookFloor1)i; InfoFloor1 info=look.vi; int n=vb.vd.vi.blocksizes[vb.mode]/2; if(memo!=null) { /* render the lines */ int[] fit_value=(int[] )memo; int hx=0; int lx=0; int ly=fit_value[0]*info.mult; for(int j=1;j=adx) { err-=adx; y+=sy; } else { y+=bbase; } d[x]*=FLOOR_fromdB_LOOKUP[y]; } } static int ilog(int v) { int ret=0; while(v!=0) { ret++; v = (int)((uint)v >> 1); } return(ret); } private static int ilog2(int v) { int ret=0; while(v>1) { ret++; v = (int)((uint)v >> 1); } return(ret); } } class InfoFloor1 { const int VIF_POSIT=63; const int VIF_CLASS=16; const int VIF_PARTS=31; internal int partitions; /* 0 to 31 */ internal int[] partitionclass=new int[VIF_PARTS]; /* 0 to 15 */ internal int[] class_dim=new int[VIF_CLASS]; /* 1 to 8 */ internal int[] class_subs=new int[VIF_CLASS]; /* 0,1,2,3 (bits: 1<