]> Joshua Wise's Git repositories - patchfork.git/blob - jorbis/src/com/jcraft/jorbis/Mapping0.java
initial import from pitchfork-0.5.5
[patchfork.git] / jorbis / src / com / jcraft / jorbis / Mapping0.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 Mapping0 extends FuncMapping{
31   static int seq=0;
32   void free_info(Object imap){};
33   void free_look(Object imap){
34 /*
35     LookMapping0 l=(LookMapping0)imap;
36     InfoMapping0 info=l.map;
37     if(l!=null){
38       for(int i=0;i<l.map.submaps;i++){
39         l.time_func[i].free_look(l.time_look[i]);
40         l.floor_func[i].free_look(l.floor_look[i]);
41         l.residue_func[i].free_look(l.residue_look[i]);
42         if(l.psy_look!=null)l.psy_look[i].clear();
43       }
44     }
45
46     if(l.floor_state!=null){
47       for(int i=0;i<l.ch;i++)
48         l.floor_func[info.chmuxlist[i]].free_state(l.floor_state[i]);
49       //free(l.floor_state);
50     }
51
52     if(l.decay!=null){
53       for(int i=0;i<l.ch;i++){
54         //if(l.decay[i])free(l->decay[i]);
55         l.decay[i]=null;
56       }
57       //free(l->decay);
58       l.decay=null;
59     }
60     //free(l->time_func);
61     //free(l->floor_func);
62     //free(l->residue_func);
63     //free(l->time_look);
64     //free(l->floor_look);
65     //free(l->residue_look);
66     //f(l->psy_look)free(l->psy_look);
67     l.time_func=null;
68     l.floor_func=null;
69     l.residue_func=null;
70     l.time_look=null;
71     l.floor_look=null;
72     l.residue_look=null;
73     //memset(l,0,sizeof(vorbis_look_mapping0));
74     //free(l);
75 */
76   }
77
78   Object look(DspState vd, InfoMode vm, Object m){
79 //System.err.println("Mapping0.look");
80     Info vi=vd.vi;
81     LookMapping0 look=new LookMapping0();
82     InfoMapping0 info=look.map=(InfoMapping0)m;
83     look.mode=vm;
84   
85     look.time_look=new Object[info.submaps];
86     look.floor_look=new Object[info.submaps];
87     look.residue_look=new Object[info.submaps];
88
89 /*
90     if(vd.analysisp!=0){
91       look.floor_state=new Object[vi.channels];
92     }
93     if(vi.psys!=0){
94       look.psy_look=new PsyLook[info.submaps];
95       for(int i=0; i<info.submaps; i++){ look.psy_look[i]=new PsyLook(); }
96     }
97 */
98
99     look.time_func=new FuncTime[info.submaps];
100     look.floor_func=new FuncFloor[info.submaps];
101     look.residue_func=new FuncResidue[info.submaps];
102   
103     for(int i=0;i<info.submaps;i++){
104       int timenum=info.timesubmap[i];
105       int floornum=info.floorsubmap[i];
106       int resnum=info.residuesubmap[i];
107
108       look.time_func[i]=FuncTime.time_P[vi.time_type[timenum]];
109       look.time_look[i]=look.time_func[i].look(vd,vm,vi.time_param[timenum]);
110       look.floor_func[i]=FuncFloor.floor_P[vi.floor_type[floornum]];
111       look.floor_look[i]=look.floor_func[i].
112                          look(vd,vm,vi.floor_param[floornum]);
113       look.residue_func[i]=FuncResidue.residue_P[vi.residue_type[resnum]];
114       look.residue_look[i]=look.residue_func[i].
115                            look(vd,vm,vi.residue_param[resnum]);
116
117 /*    
118       if(vi.psys!=0 && vd.analysisp!=0){
119         int psynum=info.psysubmap[i];
120         look.psy_look[i].init(vi.psy_param[psynum],
121                               vi.blocksizes[vm.blockflag]/2,vi.rate);
122       }
123 */
124     }
125
126     if(vi.psys!=0 && vd.analysisp!=0){
127         /*
128     if(info->psy[0] != info->psy[1]){
129
130       int psynum=info->psy[0];
131       look->psy_look[0]=_ogg_calloc(1,sizeof(vorbis_look_psy));      
132       _vp_psy_init(look->psy_look[0],ci->psy_param[psynum],
133                    ci->psy_g_param,
134                    ci->blocksizes[vm->blockflag]/2,vi->rate);
135
136       psynum=info->psy[1];
137       look->psy_look[1]=_ogg_calloc(1,sizeof(vorbis_look_psy));      
138       _vp_psy_init(look->psy_look[1],ci->psy_param[psynum],
139                    ci->psy_g_param,
140                    ci->blocksizes[vm->blockflag]/2,vi->rate);
141     }else{
142
143       int psynum=info->psy[0];
144       look->psy_look[0]=_ogg_calloc(1,sizeof(vorbis_look_psy));      
145       look->psy_look[1]=look->psy_look[0];
146      _vp_psy_init(look->psy_look[0],ci->psy_param[psynum],
147                    ci->psy_g_param,
148                    ci->blocksizes[vm->blockflag]/2,vi->rate);
149
150     }
151         */
152     }
153
154     look.ch=vi.channels;
155 //  if(vd->analysisp)drft_init(&look->fft_look,ci->blocksizes[vm->blockflag]);
156
157     return(look);
158 //return null;
159   }
160
161   void pack(Info vi, Object imap, Buffer opb){
162     InfoMapping0 info=(InfoMapping0)imap;
163
164   /* another 'we meant to do it this way' hack...  up to beta 4, we
165      packed 4 binary zeros here to signify one submapping in use.  We
166      now redefine that to mean four bitflags that indicate use of
167      deeper features; bit0:submappings, bit1:coupling,
168      bit2,3:reserved. This is backward compatable with all actual uses
169      of the beta code. */
170
171     if(info.submaps>1){
172       opb.write(1,1);
173       opb.write(info.submaps-1,4);
174     }
175     else{
176       opb.write(0,1);
177     }
178
179     if(info.coupling_steps>0){
180       opb.write(1,1);
181       opb.write(info.coupling_steps-1,8);
182       for(int i=0;i<info.coupling_steps;i++){
183         opb.write(info.coupling_mag[i],ilog2(vi.channels));
184         opb.write(info.coupling_ang[i],ilog2(vi.channels));
185       }
186     }
187     else{
188       opb.write(0,1);
189     }
190   
191     opb.write(0,2); /* 2,3:reserved */
192
193     /* we don't write the channel submappings if we only have one... */
194     if(info.submaps>1){
195       for(int i=0;i<vi.channels;i++)
196         opb.write(info.chmuxlist[i],4);
197     }
198     for(int i=0;i<info.submaps;i++){
199       opb.write(info.timesubmap[i],8);
200       opb.write(info.floorsubmap[i],8);
201       opb.write(info.residuesubmap[i],8);
202     }
203   }
204
205   // also responsible for range checking
206   Object unpack(Info vi, Buffer opb){
207     InfoMapping0 info=new InfoMapping0();
208
209     // !!!!
210     if(opb.read(1)!=0){
211       info.submaps=opb.read(4)+1;
212     }
213     else{
214       info.submaps=1;
215     }
216
217     if(opb.read(1)!=0){
218       info.coupling_steps=opb.read(8)+1;
219
220       for(int i=0;i<info.coupling_steps;i++){
221         int testM=info.coupling_mag[i]=opb.read(ilog2(vi.channels));
222         int testA=info.coupling_ang[i]=opb.read(ilog2(vi.channels));
223
224         if(testM<0 ||
225            testA<0 ||
226            testM==testA ||
227            testM>=vi.channels ||
228            testA>=vi.channels){
229           //goto err_out;
230           info.free();
231           return(null);
232         }
233       }
234     }
235
236     if(opb.read(2)>0){ /* 2,3:reserved */
237       //goto err_out;
238       info.free();
239       return(null);
240     }
241
242     if(info.submaps>1){
243       for(int i=0;i<vi.channels;i++){
244         info.chmuxlist[i]=opb.read(4);
245         if(info.chmuxlist[i]>=info.submaps){
246           //goto err_out;
247           info.free();
248           return(null);
249         }
250       }
251     }
252
253     for(int i=0;i<info.submaps;i++){
254       info.timesubmap[i]=opb.read(8);
255       if(info.timesubmap[i]>=vi.times){
256         //goto err_out;
257         info.free();
258         return(null);
259       }
260       info.floorsubmap[i]=opb.read(8);
261       if(info.floorsubmap[i]>=vi.floors){
262         //goto err_out;
263         info.free();
264         return(null);
265       }
266       info.residuesubmap[i]=opb.read(8);
267       if(info.residuesubmap[i]>=vi.residues){
268         //goto err_out;
269         info.free();
270         return(null);
271       }
272     }
273     return info;
274     //err_out:
275     //free_info(info);
276     //return(NULL);
277   }
278
279 /*
280   // no time mapping implementation for now 
281   static int seq=0;
282   int forward(Block vb, Object l){
283     DspState vd=vb.vd;
284     Info vi=vd.vi;
285     LookMapping0 look=(LookMapping0)l;
286     InfoMapping0 info=look.map;
287     InfoMode mode=look.mode;
288     int n=vb.pcmend;
289     float[] window=vd.window[vb.W][vb.lW][vb.nW][mode.windowtype];
290
291     float[][] pcmbundle=new float[vi.channles][];
292     int[] nonzero=new int[vi.channels];
293  
294      // time domain pre-window: NONE IMPLEMENTED
295
296      // window the PCM data: takes PCM vector, vb; modifies PCM vector
297
298      for(int i=0;i<vi.channels;i++){
299        float[] pcm=vb.pcm[i];
300        for(int j=0;j<n;j++)
301          pcm[j]*=window[j];
302      }
303             
304      // time-domain post-window: NONE IMPLEMENTED
305
306      // transform the PCM data; takes PCM vector, vb; modifies PCM vector
307      // only MDCT right now....
308      for(int i=0;i<vi.channels;i++){
309        float[] pcm=vb.pcm[i];
310        mdct_forward(vd.transform[vb.W][0],pcm,pcm);
311      }
312
313      {
314        float[] floor=_vorbis_block_alloc(vb,n*sizeof(float)/2);
315     
316        for(int i=0;i<vi.channels;i++){
317          float[] pcm=vb.pcm[i];
318          float[] decay=look.decay[i];
319          int submap=info.chmuxlist[i];
320
321          // if some other mode/mapping was called last frame, our decay
322          // accumulator is out of date.  Clear it.
323          //if(look.lastframe+1 != vb->sequence)
324          //  memset(decay,0,n*sizeof(float)/2);
325
326          // perform psychoacoustics; do masking
327          _vp_compute_mask(look.psy_look[submap],pcm,floor,decay);
328  
329          _analysis_output("mdct",seq,pcm,n/2,0,1);
330          _analysis_output("lmdct",seq,pcm,n/2,0,0);
331          _analysis_output("prefloor",seq,floor,n/2,0,1);
332
333          // perform floor encoding
334          nonzero[i]=look.floor_func[submap].
335                     forward(vb,look.floor_look[submap],floor,floor,look.floor_state[i]);
336
337          _analysis_output("floor",seq,floor,n/2,0,1);
338
339          // apply the floor, do optional noise levelling
340          _vp_apply_floor(look->psy_look+submap,pcm,floor);
341       
342          _analysis_output("res",seq++,pcm,n/2,0,0);
343      }
344     
345      // perform residue encoding with residue mapping; this is
346      // multiplexed.  All the channels belonging to one submap are
347      // encoded (values interleaved), then the next submap, etc
348     
349      for(int i=0;i<info.submaps;i++){
350        int ch_in_bundle=0;
351         for(int j=0;j<vi.channels;j++){
352           if(info.chmuxlist[j]==i && nonzero[j]==1){
353             pcmbundle[ch_in_bundle++]=vb.pcm[j];
354           }
355         }
356         look.residue_func[i].forward(vb,look.residue_look[i], pcmbundle,ch_in_bundle);
357       }
358     }
359     look.lastframe=vb.sequence;
360     return(0);
361   }
362 */
363
364   float[][] pcmbundle=null;
365   int[] zerobundle=null;
366   int[] nonzero=null;
367   Object[] floormemo=null;
368
369   synchronized int inverse(Block vb, Object l){
370     //System.err.println("Mapping0.inverse");
371     DspState vd=vb.vd;
372     Info vi=vd.vi;
373     LookMapping0 look=(LookMapping0)l;
374     InfoMapping0 info=look.map;
375     InfoMode mode=look.mode;
376     int n=vb.pcmend=vi.blocksizes[vb.W];
377
378     float[] window=vd.window[vb.W][vb.lW][vb.nW][mode.windowtype];
379     // float[][] pcmbundle=new float[vi.channels][];
380     // int[] nonzero=new int[vi.channels];
381     if(pcmbundle==null || pcmbundle.length<vi.channels){
382       pcmbundle=new float[vi.channels][];
383       nonzero=new int[vi.channels];
384       zerobundle=new int[vi.channels];
385       floormemo=new Object[vi.channels];
386     }
387   
388     // time domain information decode (note that applying the
389     // information would have to happen later; we'll probably add a
390     // function entry to the harness for that later
391     // NOT IMPLEMENTED
392
393     // recover the spectral envelope; store it in the PCM vector for now 
394     for(int i=0;i<vi.channels;i++){
395       float[] pcm=vb.pcm[i];
396       int submap=info.chmuxlist[i];
397
398       floormemo[i]=look.floor_func[submap].inverse1(vb,look.
399                                                     floor_look[submap],
400                                                     floormemo[i]
401                                                     );
402       if(floormemo[i]!=null){ nonzero[i]=1; }
403       else{ nonzero[i]=0; }
404       for(int j=0; j<n/2; j++){
405         pcm[j]=0;
406       }                 
407
408       //_analysis_output("ifloor",seq+i,pcm,n/2,0,1);
409     }
410
411     for(int i=0; i<info.coupling_steps; i++){
412       if(nonzero[info.coupling_mag[i]]!=0 ||
413          nonzero[info.coupling_ang[i]]!=0){
414         nonzero[info.coupling_mag[i]]=1;
415         nonzero[info.coupling_ang[i]]=1;
416       }
417     }
418
419     // recover the residue, apply directly to the spectral envelope
420
421     for(int i=0;i<info.submaps;i++){
422       int ch_in_bundle=0;
423       for(int j=0;j<vi.channels;j++){
424         if(info.chmuxlist[j]==i){
425           if(nonzero[j]!=0){
426             zerobundle[ch_in_bundle]=1;
427           }
428           else{
429             zerobundle[ch_in_bundle]=0;
430           }
431           pcmbundle[ch_in_bundle++]=vb.pcm[j];
432         }
433       }
434
435       look.residue_func[i].inverse(vb,look.residue_look[i],
436                                    pcmbundle,zerobundle,ch_in_bundle);
437     }
438
439
440     for(int i=info.coupling_steps-1;i>=0;i--){
441       float[] pcmM=vb.pcm[info.coupling_mag[i]];
442       float[] pcmA=vb.pcm[info.coupling_ang[i]];
443
444       for(int j=0;j<n/2;j++){
445         float mag=pcmM[j];
446         float ang=pcmA[j];
447
448         if(mag>0){
449           if(ang>0){
450             pcmM[j]=mag;
451             pcmA[j]=mag-ang;
452           }
453           else{
454             pcmA[j]=mag;
455             pcmM[j]=mag+ang;
456           }
457         }
458         else{
459           if(ang>0){
460             pcmM[j]=mag;
461             pcmA[j]=mag+ang;
462           }
463           else{
464             pcmA[j]=mag;
465             pcmM[j]=mag-ang;
466           }
467         }
468       }
469     }
470
471 //    /* compute and apply spectral envelope */
472
473     for(int i=0;i<vi.channels;i++){
474       float[] pcm=vb.pcm[i];
475       int submap=info.chmuxlist[i];
476       look.floor_func[submap].inverse2(vb,look.floor_look[submap],floormemo[i],pcm);
477     }
478
479     // transform the PCM data; takes PCM vector, vb; modifies PCM vector
480     // only MDCT right now....
481
482     for(int i=0;i<vi.channels;i++){
483       float[] pcm=vb.pcm[i];
484       //_analysis_output("out",seq+i,pcm,n/2,0,0);
485       ((Mdct)vd.transform[vb.W][0]).backward(pcm,pcm);
486     }
487
488     // now apply the decoded pre-window time information
489     // NOT IMPLEMENTED
490   
491     // window the data
492     for(int i=0;i<vi.channels;i++){
493       float[] pcm=vb.pcm[i];
494       if(nonzero[i]!=0){
495         for(int j=0;j<n;j++){
496           pcm[j]*=window[j];
497         }
498       }
499       else{
500         for(int j=0;j<n;j++){
501           pcm[j]=0.f;
502         }
503       }
504       //_analysis_output("final",seq++,pcm,n,0,0);
505     }
506             
507     // now apply the decoded post-window time information
508     // NOT IMPLEMENTED
509     // all done!
510     return(0);
511   }
512
513
514   private static int ilog2(int v){
515     int ret=0;
516     while(v>1){
517       ret++;
518       v>>>=1;
519     }
520     return(ret);
521   }
522 }
523
524 class InfoMapping0{
525   int   submaps;  // <= 16
526   int[] chmuxlist=new int[256];   // up to 256 channels in a Vorbis stream
527   
528   int[] timesubmap=new int[16];   // [mux]
529   int[] floorsubmap=new int[16];  // [mux] submap to floors
530   int[] residuesubmap=new int[16];// [mux] submap to residue
531   int[] psysubmap=new int[16];    // [mux]; encode only
532
533   int   coupling_steps;
534   int[] coupling_mag=new int[256];
535   int[] coupling_ang=new int[256];
536
537   void free(){
538     chmuxlist=null;
539     timesubmap=null;
540     floorsubmap=null;
541     residuesubmap=null;
542     psysubmap=null;
543
544     coupling_mag=null;
545     coupling_ang=null;
546   }
547 }
548
549 class LookMapping0{
550   InfoMode mode;
551   InfoMapping0 map;
552   Object[] time_look;
553   Object[] floor_look;
554   Object[] floor_state;
555   Object[] residue_look; 
556   PsyLook[] psy_look;
557
558   FuncTime[] time_func; 
559   FuncFloor[] floor_func; 
560   FuncResidue[] residue_func;
561
562   int ch;
563   float[][] decay;
564   int lastframe; // if a different mode is called, we need to 
565                  // invalidate decay and floor state
566 }
This page took 0.049904 seconds and 4 git commands to generate.