]> Joshua Wise's Git repositories - patchfork.git/blob - jorbis/src/com/jcraft/jorbis/Floor0.java
initial import from pitchfork-0.5.5
[patchfork.git] / jorbis / src / com / jcraft / jorbis / Floor0.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 Floor0 extends FuncFloor{
31
32   void pack(Object i, Buffer opb){
33     InfoFloor0 info=(InfoFloor0)i;
34     opb.write(info.order,8);
35     opb.write(info.rate,16);
36     opb.write(info.barkmap,16);
37     opb.write(info.ampbits,6);
38     opb.write(info.ampdB,8);
39     opb.write(info.numbooks-1,4);
40     for(int j=0;j<info.numbooks;j++)
41       opb.write(info.books[j],8);
42   }
43
44   Object unpack(Info vi , Buffer opb){
45     InfoFloor0 info=new InfoFloor0();
46     info.order=opb.read(8);
47     info.rate=opb.read(16);
48     info.barkmap=opb.read(16);
49     info.ampbits=opb.read(6);
50     info.ampdB=opb.read(8);
51     info.numbooks=opb.read(4)+1;
52   
53     if((info.order<1)||
54        (info.rate<1)||
55        (info.barkmap<1)||
56        (info.numbooks<1)){
57       //free_info(info);
58       return(null);
59     }
60
61     for(int j=0;j<info.numbooks;j++){
62       info.books[j]=opb.read(8);
63       if(info.books[j]<0 || info.books[j]>=vi.books){
64         //free_info(info);
65         return(null);
66       }
67     }
68     return(info);  
69 //  err_out:
70 //    free_info(info);
71 //    return(NULL);
72   }
73   Object look(DspState vd, InfoMode mi, Object i){
74     float scale;
75     Info vi=vd.vi;
76     InfoFloor0 info=(InfoFloor0)i;
77     LookFloor0 look=new LookFloor0();
78     look.m=info.order;
79     look.n=vi.blocksizes[mi.blockflag]/2;
80     look.ln=info.barkmap;
81     look.vi=info;
82     look.lpclook.init(look.ln,look.m);
83
84     // we choose a scaling constant so that:
85     //  floor(bark(rate/2-1)*C)=mapped-1
86     // floor(bark(rate/2)*C)=mapped
87     scale=look.ln/toBARK((float)(info.rate/2.));
88
89     // the mapping from a linear scale to a smaller bark scale is
90     // straightforward.  We do *not* make sure that the linear mapping
91     // does not skip bark-scale bins; the decoder simply skips them and
92     // the encoder may do what it wishes in filling them.  They're
93     // necessary in some mapping combinations to keep the scale spacing
94     // accurate
95     look.linearmap=new int[look.n];
96     for(int j=0;j<look.n;j++){
97       int val=(int)Math.floor(toBARK((float)((info.rate/2.)/look.n*j)) 
98                               *scale); // bark numbers represent band edges
99       if(val>=look.ln)val=look.ln; // guard against the approximation
100       look.linearmap[j]=val;
101     }
102     return look;
103   }
104
105   static float toBARK(float f){
106     return (float)(13.1*Math.atan(.00074*(f))+2.24*Math.atan((f)*(f)*1.85e-8)+1e-4*(f));
107   }
108
109   Object state(Object i){
110     EchstateFloor0 state=new EchstateFloor0();
111     InfoFloor0 info=(InfoFloor0)i;
112
113     // a safe size if usually too big (dim==1)
114     state.codewords=new int[info.order];
115     state.curve=new float[info.barkmap];
116     state.frameno=-1;
117     return(state);
118   }
119   void free_info(Object i){}
120   void free_look(Object i){}
121   void free_state(Object vs){}
122   int forward(Block vb, Object i,  float[] in, float[] out, Object vs){return 0;}
123
124   float[] lsp=null;    
125   int inverse(Block vb, Object i, float[] out){
126     //System.err.println("Floor0.inverse "+i.getClass()+"]");
127     LookFloor0 look=(LookFloor0)i;
128     InfoFloor0 info=look.vi;
129     int ampraw=vb.opb.read(info.ampbits);
130     if(ampraw>0){ // also handles the -1 out of data case
131       int maxval=(1<<info.ampbits)-1;
132       float amp=(float)ampraw/maxval*info.ampdB;
133       int booknum=vb.opb.read(ilog(info.numbooks));
134
135       if(booknum!=-1 && booknum<info.numbooks){
136
137         synchronized(this){ 
138         if(lsp==null||lsp.length<look.m){
139           lsp=new float[look.m];
140         }         
141         else{
142           for(int j=0; j<look.m; j++)lsp[j]=0.f;
143         }
144
145         CodeBook b=vb.vd.fullbooks[info.books[booknum]];
146         float last=0.f;
147
148         //memset(out,0,sizeof(float)*look->m);
149         for(int j=0; j<look.m; j++)out[j]=0.0f;
150
151         for(int j=0;j<look.m;j+=b.dim){
152           if(b.decodevs(lsp, j, vb.opb, 1, -1)==-1){
153             //goto eop;
154             // memset(out,0,sizeof(float)*look->n);
155             for(int k=0; k<look.n; k++)out[k]=0.0f;
156             return(0);
157           }
158         }
159         for(int j=0;j<look.m;){
160           for(int k=0;k<b.dim;k++,j++)lsp[j]+=last;
161           last=lsp[j-1];
162         }
163         // take the coefficients back to a spectral envelope curve
164         /*
165         lsp_to_lpc(out,out,look.m); 
166         lpc_to_curve(out,out,amp,look,"",0);
167         for(int j=0;j<look.n;j++){
168           out[j]=fromdB(out[j]-info.ampdB);
169         }
170         */
171         Lsp.lsp_to_curve(out,look.linearmap,look.n,look.ln,                 
172                          lsp,look.m,amp,info.ampdB);    
173
174         return(1);
175         }
176       }
177     }
178 //  eop:
179 //    memset(out,0,sizeof(float)*look->n);
180     return(0);
181   }
182
183   Object inverse1(Block vb, Object i, Object memo){
184     //System.err.println("Floor0.inverse "+i.getClass()+"]");
185     LookFloor0 look=(LookFloor0)i;
186     InfoFloor0 info=look.vi;
187     float[] lsp=null;
188     if(memo instanceof float[]){
189       lsp=(float[])memo;
190     }
191
192     int ampraw=vb.opb.read(info.ampbits);
193     if(ampraw>0){ // also handles the -1 out of data case
194       int maxval=(1<<info.ampbits)-1;
195       float amp=(float)ampraw/maxval*info.ampdB;
196       int booknum=vb.opb.read(ilog(info.numbooks));
197
198       if(booknum!=-1 && booknum<info.numbooks){
199         CodeBook b=vb.vd.fullbooks[info.books[booknum]];
200         float last=0.f;
201
202         if(lsp==null||lsp.length<look.m+1){
203           lsp=new float[look.m+1];
204         }         
205         else{
206           for(int j=0; j<lsp.length; j++)lsp[j]=0.f;
207         }
208
209         for(int j=0;j<look.m;j+=b.dim){
210           if(b.decodev_set(lsp, j, vb.opb, b.dim)==-1){
211             //goto eop;
212             return(null);
213           }
214         }
215
216         for(int j=0;j<look.m;){
217           for(int k=0;k<b.dim;k++,j++)lsp[j]+=last;
218           last=lsp[j-1];
219         }
220         lsp[look.m]=amp;
221         return(lsp);
222       }
223     }
224 //  eop:
225     return(null);
226   }
227
228   int inverse2(Block vb, Object i, Object memo, float[] out){
229     //System.err.println("Floor0.inverse "+i.getClass()+"]");
230     LookFloor0 look=(LookFloor0)i;
231     InfoFloor0 info=look.vi;
232
233     if(memo!=null){
234       float[] lsp=(float[])memo;
235       float amp=lsp[look.m];
236
237       Lsp.lsp_to_curve(out,look.linearmap,look.n,look.ln,                 
238                        lsp,look.m,amp,info.ampdB);    
239       return(1);
240     }
241 //  eop:
242 //    memset(out,0,sizeof(float)*look->n);
243     for(int j=0; j<look.n; j++){
244       out[j]=0.f;
245     } 
246     return(0);
247   }
248
249   static float fromdB(float x){
250     return (float)(Math.exp((x)*.11512925));
251   }
252   private static int ilog(int v){
253     int ret=0;
254     while(v!=0){
255       ret++;
256       v>>>=1;
257     }
258     return(ret);
259   }
260
261   static void lsp_to_lpc(float[] lsp, float[] lpc, int m){ 
262     int i,j,m2=m/2;
263     float[] O=new float[m2];
264     float[] E=new float[m2];
265     float A;
266     float[] Ae=new float[m2+1];
267     float[] Ao=new float[m2+1];
268     float B;
269     float[] Be=new float[m2];
270     float[] Bo=new float[m2];
271     float temp;
272
273     // even/odd roots setup
274     for(i=0;i<m2;i++){
275       O[i]=(float)(-2.*Math.cos(lsp[i*2]));
276       E[i]=(float)(-2.*Math.cos(lsp[i*2+1]));
277     }
278
279     // set up impulse response
280     for(j=0;j<m2;j++){
281       Ae[j]=0.f;
282       Ao[j]=1.f;
283       Be[j]=0.f;
284       Bo[j]=1.f;
285     }
286     Ao[j]=1.f;
287     Ae[j]=1.f;
288
289     // run impulse response
290     for(i=1;i<m+1;i++){
291       A=B=0.f;
292       for(j=0;j<m2;j++){
293         temp=O[j]*Ao[j]+Ae[j];
294         Ae[j]=Ao[j];
295         Ao[j]=A;
296         A+=temp;
297
298         temp=E[j]*Bo[j]+Be[j];
299         Be[j]=Bo[j];
300         Bo[j]=B;
301         B+=temp;
302       }
303       lpc[i-1]=(A+Ao[j]+B-Ae[j])/2;
304       Ao[j]=A;
305       Ae[j]=B;
306     }
307   }
308
309   static void lpc_to_curve(float[] curve, float[] lpc,float amp,
310                            LookFloor0 l, String name, int frameno){
311     // l->m+1 must be less than l->ln, but guard in case we get a bad stream
312     float[] lcurve=new float[Math.max(l.ln*2,l.m*2+2)];
313
314     if(amp==0){
315       //memset(curve,0,sizeof(float)*l->n);
316       for(int j=0; j<l.n; j++)curve[j]=0.0f;
317       return;
318     }
319     l.lpclook.lpc_to_curve(lcurve,lpc,amp);
320
321     for(int i=0;i<l.n;i++)curve[i]=lcurve[l.linearmap[i]];
322   }
323 }
324
325 class InfoFloor0{
326   int order;
327   int rate;
328   int barkmap;
329
330   int   ampbits;
331   int   ampdB;
332
333   int   numbooks; // <= 16
334   int[]  books=new int[16];
335 }
336
337 class LookFloor0{
338   int n;
339   int ln;
340   int m;
341   int[] linearmap;
342
343   InfoFloor0 vi;
344   Lpc lpclook=new Lpc();
345 }
346
347 class EchstateFloor0{
348   int[] codewords;
349   float[] curve;
350   long frameno;
351   long codes;
352 }
This page took 0.040988 seconds and 4 git commands to generate.