]> Joshua Wise's Git repositories - patchfork.git/blob - jorbis/src/com/jcraft/jorbis/Residue0.java
Add support for view-only mode.
[patchfork.git] / jorbis / src / com / jcraft / jorbis / Residue0.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 Residue0 extends FuncResidue{
31   void pack(Object vr, Buffer opb){
32     InfoResidue0 info=(InfoResidue0)vr;
33     int acc=0;
34     opb.write(info.begin,24);
35     opb.write(info.end,24);
36
37     opb.write(info.grouping-1,24);  /* residue vectors to group and 
38                                      code with a partitioned book */
39     opb.write(info.partitions-1,6); /* possible partition choices */
40     opb.write(info.groupbook,8);  /* group huffman book */
41
42     /* secondstages is a bitmask; as encoding progresses pass by pass, a
43        bitmask of one indicates this partition class has bits to write
44        this pass */
45     for(int j=0;j<info.partitions;j++){
46       if(ilog(info.secondstages[j])>3){
47       /* yes, this is a minor hack due to not thinking ahead */
48         opb.write(info.secondstages[j],3); 
49         opb.write(1,1);
50         opb.write(info.secondstages[j]>>>3,5); 
51       }
52       else{
53         opb.write(info.secondstages[j],4); /* trailing zero */
54       }
55       acc+=icount(info.secondstages[j]);
56    }
57     for(int j=0;j<acc;j++){
58       opb.write(info.booklist[j],8);
59     }
60   }
61
62   Object unpack(Info vi, Buffer opb){
63     int acc=0;
64     InfoResidue0 info=new InfoResidue0();
65
66     info.begin=opb.read(24);
67     info.end=opb.read(24);
68     info.grouping=opb.read(24)+1;
69     info.partitions=opb.read(6)+1;
70     info.groupbook=opb.read(8);
71
72     for(int j=0;j<info.partitions;j++){
73       int cascade=opb.read(3);
74       if(opb.read(1)!=0){
75         cascade|=(opb.read(5)<<3);
76       }
77       info.secondstages[j]=cascade;
78       acc+=icount(cascade);
79     }
80
81     for(int j=0;j<acc;j++){
82       info.booklist[j]=opb.read(8);
83 //    if(info.booklist[j]==255)info.booklist[j]=-1;
84     }
85
86     if(info.groupbook>=vi.books){
87       free_info(info);
88       return(null);
89     }
90
91     for(int j=0;j<acc;j++){
92       if(info.booklist[j]>=vi.books){
93         free_info(info);
94         return(null);
95       }
96     }
97     return(info);
98 //  errout:
99 //    free_info(info);
100 //    return(NULL);
101   }
102
103   Object look(DspState vd, InfoMode vm, Object vr){
104     InfoResidue0 info=(InfoResidue0)vr;
105     LookResidue0 look=new LookResidue0();
106     int acc=0;
107     int dim;
108     int maxstage=0;
109     look.info=info;
110     look.map=vm.mapping;
111
112     look.parts=info.partitions;
113     look.fullbooks=vd.fullbooks;
114     look.phrasebook=vd.fullbooks[info.groupbook];
115
116     dim=look.phrasebook.dim;
117
118     look.partbooks=new int[look.parts][];
119
120     for(int j=0;j<look.parts;j++){
121       int stages=ilog(info.secondstages[j]);
122       if(stages!=0){
123         if(stages>maxstage)maxstage=stages;
124         look.partbooks[j]=new int[stages];
125         for(int k=0; k<stages; k++){
126           if((info.secondstages[j]&(1<<k))!=0){
127             look.partbooks[j][k]=info.booklist[acc++];
128           }
129         }
130       }
131     }
132
133     look.partvals=(int)Math.rint(Math.pow(look.parts,dim));
134     look.stages=maxstage;
135     look.decodemap=new int[look.partvals][];
136     for(int j=0;j<look.partvals;j++){
137       int val=j;
138       int mult=look.partvals/look.parts;
139       look.decodemap[j]=new int[dim];
140
141       for(int k=0;k<dim;k++){
142         int deco=val/mult;
143         val-=deco*mult;
144         mult/=look.parts;
145         look.decodemap[j][k]=deco;
146       }
147     }
148     return(look);
149   }
150   void free_info(Object i){}
151   void free_look(Object i){}
152   int forward(Block vb,Object vl, float[][] in, int ch){
153     System.err.println("Residue0.forward: not implemented");
154     return 0;
155   }
156
157   static int[][][] partword=new int[2][][]; // _01inverse is synchronized for
158                                             // re-using partword
159   synchronized static int _01inverse(Block vb, Object vl, 
160                                      float[][] in,int ch,int decodepart){
161     int i,j,k,l,s;
162     LookResidue0 look=(LookResidue0 )vl;
163     InfoResidue0 info=look.info;
164
165     // move all this setup out later
166     int samples_per_partition=info.grouping;
167     int partitions_per_word=look.phrasebook.dim;
168     int n=info.end-info.begin;
169   
170     int partvals=n/samples_per_partition;
171     int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
172
173     if(partword.length<ch){
174       partword=new int[ch][][];
175       for(j=0;j<ch;j++){
176         partword[j]=new int[partwords][];
177       }
178     }
179     else{
180       for(j=0;j<ch;j++){
181         if(partword[j]==null || partword[j].length<partwords)
182           partword[j]=new int[partwords][];
183       }
184     }
185
186     for(s=0;s<look.stages;s++){
187       // each loop decodes on partition codeword containing 
188       // partitions_pre_word partitions
189       for(i=0,l=0;i<partvals;l++){
190         if(s==0){
191           // fetch the partition word for each channel
192           for(j=0;j<ch;j++){
193             int temp=look.phrasebook.decode(vb.opb);
194             if(temp==-1){
195               //goto eopbreak;
196               return(0);
197             }
198             partword[j][l]=look.decodemap[temp];
199             if(partword[j][l]==null){
200 //            goto errout;
201               return(0);
202             }
203           } 
204         }
205       
206         // now we decode residual values for the partitions
207         for(k=0;k<partitions_per_word && i<partvals;k++,i++)
208           for(j=0;j<ch;j++){
209             int offset=info.begin+i*samples_per_partition;
210             if((info.secondstages[partword[j][l][k]]&(1<<s))!=0){
211               CodeBook stagebook=look.fullbooks[look.partbooks[partword[j][l][k]][s]];
212 //            CodeBook stagebook=look.partbooks[partword[j][l][k]][s];
213               if(stagebook!=null){
214                   if(decodepart==0){
215                     if(stagebook.decodevs_add(in[j],offset,vb.opb,samples_per_partition)==-1){
216                       // goto errout;
217                       return(0);
218                     }
219                   }
220                   else if(decodepart==1){
221                     if(stagebook.decodev_add(in[j], offset, vb.opb,samples_per_partition)==-1){
222                       // goto errout;
223                       return(0);
224                     }
225                   }
226               }
227             }
228           }
229       } 
230     }
231 //  errout:
232 //  eopbreak:
233   return(0);
234   }
235
236   static int _2inverse(Block vb, Object vl, float[][] in, int ch){
237     int i,j,k,l,s;
238     LookResidue0 look=(LookResidue0 )vl;
239     InfoResidue0 info=look.info;
240
241     // move all this setup out later
242     int samples_per_partition=info.grouping;
243     int partitions_per_word=look.phrasebook.dim;
244     int n=info.end-info.begin;
245   
246     int partvals=n/samples_per_partition;
247     int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
248
249     int[][] partword=new int[partwords][];
250     for(s=0;s<look.stages;s++){
251       for(i=0,l=0;i<partvals;l++){
252         if(s==0){
253           // fetch the partition word for each channel
254           int temp=look.phrasebook.decode(vb.opb);
255           if(temp==-1){
256             // goto eopbreak;
257             return(0);
258           }
259           partword[l]=look.decodemap[temp];
260           if(partword[l]==null){
261             // goto errout;
262             return(0);
263           }
264         }
265
266         // now we decode residual values for the partitions
267         for(k=0;k<partitions_per_word && i<partvals;k++,i++){
268           int offset=info.begin+i*samples_per_partition;
269           if((info.secondstages[partword[l][k]]&(1<<s))!=0){
270             CodeBook stagebook=look.fullbooks[look.partbooks[partword[l][k]][s]];
271             if(stagebook!=null){
272               if(stagebook.decodevv_add(in, offset, ch, vb.opb,samples_per_partition)==-1){
273                 // goto errout;
274                 return(0);
275               }
276             }
277           } 
278         }
279       }
280     }
281 //  errout:
282 //  eopbreak:
283     return(0);
284   }
285
286   int inverse(Block vb, Object vl, float[][] in, int[] nonzero, int ch){
287     //System.err.println("Residue0.inverse");
288     int used=0;
289     for(int i=0;i<ch;i++){
290       if(nonzero[i]!=0){
291         in[used++]=in[i];
292       }
293     }
294     if(used!=0)
295       return(_01inverse(vb,vl,in,used,0));
296     else
297       return(0);
298   }
299
300 /*
301   int inverse(Block vb, Object vl, float[][] in, int ch){
302 //System.err.println("Residue0.inverse");
303     int i,j,k,l,transend=vb.pcmend/2;
304     LookResidue0 look=(LookResidue0 )vl;
305     InfoResidue0 info=look.info;
306
307     // move all this setup out later
308     int samples_per_partition=info.grouping;
309     int partitions_per_word=look.phrasebook.dim;
310     int n=info.end-info.begin;
311
312     int partvals=n/samples_per_partition;
313     int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
314     int[][] partword=new int[ch][];
315     float[] work=new float[samples_per_partition];
316     partvals=partwords*partitions_per_word;
317
318     // make sure we're zeroed up to the start
319     for(j=0;j<ch;j++){
320       for(k=0; k<info.begin; k++)in[j][k]=0.0f;
321     }
322
323     for(i=info.begin,l=0;i<info.end;){
324       // fetch the partition word for each channel
325       for(j=0;j<ch;j++){
326         int temp=look.phrasebook.decode(vb.opb);
327         if(temp==-1){
328           //goto eopbreak;
329           if(i<transend){
330             for(j=0;j<ch;j++){
331               for(k=0;k<transend-i;k++)in[j][i+k]=0.0f;
332             }
333           }
334           return(0);
335         }
336         partword[j]=look.decodemap[temp];
337         if(partword[j]==null){
338           //goto errout;
339           for(j=0;j<ch;j++){
340             for(k=0;k<transend;k++)in[j][k]=0.0f;
341           }
342           return(0);
343         }
344       }
345     
346       // now we decode interleaved residual values for the partitions
347       for(k=0;k<partitions_per_word;k++,l++,i+=samples_per_partition){
348         for(j=0;j<ch;j++){
349           int part=partword[j][k];
350           if(decodepart(vb.opb,work, in[j], i,samples_per_partition,
351                         info.secondstages[part],
352                         look.partbooks[part])==-1){
353             //goto eopbreak;
354             if(i<transend){
355               for(j=0;j<ch;j++){
356                 for(k=0;k<transend-i;k++)in[j][i+k]=0.0f;
357               }
358             }
359             return(0);
360           }
361         }
362       }
363     }
364
365 // eopbreak:
366     if(i<transend){
367       for(j=0;j<ch;j++){
368         for(k=0;k<transend-i;k++)in[j][i+k]=0.0f;
369       }
370     }
371     return(0);
372
373 // errout:
374 //  for(j=0;j<ch;j++)
375 //    for(k=0;k<transend;k++)in[j][k]=0.0f;
376 //  return(0);
377   }
378   int decodepart(Buffer opb, float[] work, float[] vec, int veci,
379                  int n, int stages, CodeBook[] books){
380     int i,j;
381     for(i=0;i<n;i++)work[i]=0.0f;
382
383     for(j=0;j<stages;j++){
384       int dim=books[j].dim;
385       int step=n/dim;
386       for(i=0;i<step;i++){
387         if(books[j].decodevs(work, i, opb, step, 0)==-1){
388           return(-1);
389         }
390       }
391     }
392     for(i=0;i<n;i++){
393       vec[veci+i]*=work[i];
394     }
395     return(0);
396   }
397 */
398
399   private static int ilog(int v){
400     int ret=0;
401     while(v!=0){
402       ret++;
403       v>>>=1;
404     }
405     return(ret);
406   }
407   private static int icount(int v){
408     int ret=0;
409    while(v!=0){
410       ret+=(v&1);
411       v>>>=1;
412     }
413     return(ret);
414   }
415 }
416
417 class LookResidue0 {
418   InfoResidue0 info;
419   int map;
420   
421   int parts;
422   int stages;
423   CodeBook[] fullbooks;
424   CodeBook   phrasebook;
425   int[][] partbooks;
426 //  CodeBook[][] partbooks;
427
428   int partvals;
429   int[][] decodemap;
430
431   int  postbits;
432   int         phrasebits;
433 //  int[][]     frames;
434   int    frames;
435 }
436
437 class InfoResidue0{
438   // block-partitioned VQ coded straight residue
439   int begin;
440   int end;
441
442   // first stage (lossless partitioning)
443   int grouping;                   // group n vectors per partition
444   int partitions;                 // possible codebooks for a partition
445   int groupbook;                  // huffbook for partitioning
446   int[] secondstages=new int[64]; // expanded out to pointers in lookup
447   int[] booklist=new int[256];    // list of second stage books
448
449   // encode-only heuristic settings
450   float[] entmax=new float[64];       // book entropy threshholds
451   float[] ampmax=new float[64];       // book amp threshholds
452   int[] subgrp=new int[64];       // book heuristic subgroup size
453   int[] blimit=new int[64];       // subgroup position limits
454 }
This page took 0.046156 seconds and 4 git commands to generate.