/* 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 Floor0 : FuncFloor { override public void pack(Object i, csBuffer opb) { InfoFloor0 info=(InfoFloor0)i; opb.write(info.order,8); opb.write(info.rate,16); opb.write(info.barkmap,16); opb.write(info.ampbits,6); opb.write(info.ampdB,8); opb.write(info.numbooks-1,4); for(int j=0;j=vi.books) { //free_info(info); return(null); } } return(info); // err_out: // free_info(info); // return(NULL); } override public Object look(DspState vd, InfoMode mi, Object i) { float scale; Info vi=vd.vi; InfoFloor0 info=(InfoFloor0)i; LookFloor0 look=new LookFloor0(); look.m=info.order; look.n=vi.blocksizes[mi.blockflag]/2; look.ln=info.barkmap; look.vi=info; look.lpclook.init(look.ln,look.m); // we choose a scaling constant so that: // floor(bark(rate/2-1)*C)=mapped-1 // floor(bark(rate/2)*C)=mapped scale = look.ln / (float)toBARK((float)(info.rate/2.0)); // the mapping from a linear scale to a smaller bark scale is // straightforward. We do *not* make sure that the linear mapping // does not skip bark-scale bins; the decoder simply skips them and // the encoder may do what it wishes in filling them. They're // necessary in some mapping combinations to keep the scale spacing // accurate look.linearmap=new int[look.n]; for(int j=0; j=look.ln) val=look.ln; // guard against the approximation look.linearmap[j]=val; } return look; } static double toBARK(float f) { double a,b,c; a = 13.1 * Math.Atan(0.00074 * f); b = 2.24 * Math.Atan(f * f * 1.85e-8); c = 1.0e-4 * f; return (a + b + c); } private object state(object i) { EchstateFloor0 state=new EchstateFloor0(); InfoFloor0 info=(InfoFloor0)i; // a safe size if usually too big (dim==1) state.codewords=new int[info.order]; state.curve=new float[info.barkmap]; state.frameno=-1; return(state); } 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;} float[] lsp=null; int inverse(Block vb, Object i, float[] fout) { //System.err.println("Floor0.inverse "+i.getClass()+"]"); LookFloor0 look=(LookFloor0)i; InfoFloor0 info=look.vi; int ampraw=vb.opb.read(info.ampbits); if(ampraw>0) { // also handles the -1 out of data case int maxval=(1<m); for(int j=0; jn); for(int k=0; kn); return(0); } override public Object inverse1(Block vb, Object i, Object memo) { //System.err.println("Floor0.inverse "+i.getClass()+"]"); LookFloor0 look=(LookFloor0)i; InfoFloor0 info=look.vi; float[] lsp=null; if(memo is float[]) { lsp=(float[])memo; } int ampraw=vb.opb.read(info.ampbits); if(ampraw>0) { // also handles the -1 out of data case int maxval=(1<n); for(int j=0; j> 1); } return(ret); } static void lsp_to_lpc(float[] lsp, float[] lpc, int m) { int i,j,m2=m/2; float[] O=new float[m2]; float[] E=new float[m2]; float A; float[] Ae=new float[m2+1]; float[] Ao=new float[m2+1]; float B; float[] Be=new float[m2]; float[] Bo=new float[m2]; float temp; // even/odd roots setup for(i=0;im+1 must be less than l->ln, but guard in case we get a bad stream float[] lcurve=new float[Math.Max(l.ln*2,l.m*2+2)]; if(amp==0) { //memset(curve,0,sizeof(float)*l->n); for(int j=0; j