]> Joshua Wise's Git repositories - patchfork.git/blob - jorbis/src/com/jcraft/jorbis/Info.java
Add support for view-only mode.
[patchfork.git] / jorbis / src / com / jcraft / jorbis / Info.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 public class Info{
31   private static final int OV_EBADPACKET=-136;
32   private static final int OV_ENOTAUDIO=-135;
33
34   private static byte[] _vorbis="vorbis".getBytes();
35   private static final int VI_TIMEB=1;
36 //  private static final int VI_FLOORB=1;
37   private static final int VI_FLOORB=2;
38 //  private static final int VI_RESB=1;
39   private static final int VI_RESB=3;
40   private static final int VI_MAPB=1;
41   private static final int VI_WINDOWB=1;
42
43   public int version;
44   public int channels;
45   public int rate;
46
47   // The below bitrate declarations are *hints*.
48   // Combinations of the three values carry the following implications:
49   //     
50   // all three set to the same value: 
51   // implies a fixed rate bitstream
52   // only nominal set: 
53   // implies a VBR stream that averages the nominal bitrate.  No hard 
54   // upper/lower limit
55   // upper and or lower set: 
56   // implies a VBR bitstream that obeys the bitrate limits. nominal 
57   // may also be set to give a nominal rate.
58   // none set:
59   //  the coder does not care to speculate.
60
61   int bitrate_upper;
62   int bitrate_nominal;
63   int bitrate_lower;
64   
65   // Vorbis supports only short and long blocks, but allows the
66   // encoder to choose the sizes
67
68   int[] blocksizes=new int[2];
69
70   // modes are the primary means of supporting on-the-fly different
71   // blocksizes, different channel mappings (LR or mid-side),
72   // different residue backends, etc.  Each mode consists of a
73   // blocksize flag and a mapping (along with the mapping setup
74
75   int modes;
76   int maps;
77   int times;
78   int floors;
79   int residues;
80   int books;
81   int psys;     // encode only
82
83   InfoMode[] mode_param=null;
84
85   int[] map_type=null;
86   Object[] map_param=null;
87
88   int[] time_type=null;
89   Object[] time_param=null;
90
91   int[] floor_type=null;
92   Object[] floor_param=null;
93
94   int[] residue_type=null;
95   Object[] residue_param=null;
96
97   StaticCodeBook[] book_param=null;
98
99   PsyInfo[] psy_param=new PsyInfo[64]; // encode only
100   
101   // for block long/sort tuning; encode only
102   int envelopesa;
103   float preecho_thresh;
104   float preecho_clamp;
105
106   // used by synthesis, which has a full, alloced vi
107   public void init(){
108     rate=0;
109     //memset(vi,0,sizeof(vorbis_info));
110   }
111
112   public void clear(){
113     for(int i=0;i<modes;i++){ mode_param[i]=null; }
114     mode_param=null;
115
116     for(int i=0;i<maps;i++){ // unpack does the range checking
117       FuncMapping.mapping_P[map_type[i]].free_info(map_param[i]);
118     }
119     map_param=null;
120
121     for(int i=0;i<times;i++){ // unpack does the range checking
122       FuncTime.time_P[time_type[i]].free_info(time_param[i]);
123     }
124     time_param=null;
125
126     for(int i=0;i<floors;i++){ // unpack does the range checking
127       FuncFloor.floor_P[floor_type[i]].free_info(floor_param[i]);
128     }
129     floor_param=null;
130
131     for(int i=0;i<residues;i++){ // unpack does the range checking
132       FuncResidue.residue_P[residue_type[i]].free_info(residue_param[i]);
133     }
134     residue_param=null;
135
136     // the static codebooks *are* freed if you call info_clear, because
137     // decode side does alloc a 'static' codebook. Calling clear on the
138     // full codebook does not clear the static codebook (that's our
139     // responsibility)
140     for(int i=0;i<books;i++){
141       // just in case the decoder pre-cleared to save space
142       if(book_param[i]!=null){
143         book_param[i].clear();
144         book_param[i]=null;
145       }
146     }
147     //if(vi->book_param)free(vi->book_param);
148     book_param=null;
149
150     for(int i=0;i<psys;i++){
151       psy_param[i].free();
152     }
153     //if(vi->psy_param)free(vi->psy_param);
154     //memset(vi,0,sizeof(vorbis_info));
155   }
156
157   // Header packing/unpacking
158   int unpack_info(Buffer opb){
159     version=opb.read(32);
160     if(version!=0)return(-1);
161
162     channels=opb.read(8);
163     rate=opb.read(32);
164
165     bitrate_upper=opb.read(32);
166     bitrate_nominal=opb.read(32);
167     bitrate_lower=opb.read(32);
168
169     blocksizes[0]=1<<opb.read(4);
170     blocksizes[1]=1<<opb.read(4);
171   
172     if((rate<1) ||
173        (channels<1)||
174        (blocksizes[0]<8)||
175        (blocksizes[1]<blocksizes[0]) ||
176        (opb.read(1)!=1)){
177       //goto err_out; // EOP check
178       clear();
179       return(-1);
180     }
181     return(0);
182     // err_out:
183     // vorbis_info_clear(vi);
184     // return(-1);
185   }
186
187   // all of the real encoding details are here.  The modes, books,
188   // everything
189   int unpack_books(Buffer opb){
190
191     //d* codebooks
192     books=opb.read(8)+1;
193
194     if(book_param==null || book_param.length!=books)
195       book_param=new StaticCodeBook[books];
196     for(int i=0;i<books;i++){
197       book_param[i]=new StaticCodeBook();
198       if(book_param[i].unpack(opb)!=0){
199         //goto err_out;
200         clear();
201         return(-1);
202       }
203     }
204
205     // time backend settings
206     times=opb.read(6)+1;
207     if(time_type==null || time_type.length!=times) time_type=new int[times];
208     if(time_param==null || time_param.length!=times)
209       time_param=new Object[times];
210     for(int i=0;i<times;i++){
211       time_type[i]=opb.read(16);
212       if(time_type[i]<0 || time_type[i]>=VI_TIMEB){
213         //goto err_out;
214         clear();
215         return(-1);
216       }
217       time_param[i]=FuncTime.time_P[time_type[i]].unpack(this, opb);
218       if(time_param[i]==null){
219         //goto err_out;
220         clear();
221         return(-1);
222       }
223     }
224
225     // floor backend settings
226     floors=opb.read(6)+1;
227     if(floor_type==null || floor_type.length!=floors)
228       floor_type=new int[floors];
229     if(floor_param==null || floor_param.length!=floors)
230       floor_param=new Object[floors];
231
232     for(int i=0;i<floors;i++){
233       floor_type[i]=opb.read(16);
234       if(floor_type[i]<0 || floor_type[i]>=VI_FLOORB){
235         //goto err_out;
236         clear();
237         return(-1);
238       }
239
240       floor_param[i]=FuncFloor.floor_P[floor_type[i]].unpack(this,opb);
241       if(floor_param[i]==null){
242         //goto err_out;
243         clear();
244         return(-1);
245       }
246     }
247
248     // residue backend settings
249     residues=opb.read(6)+1;
250
251     if(residue_type==null || residue_type.length!=residues)
252       residue_type=new int[residues];
253
254     if(residue_param==null || residue_param.length!=residues)
255       residue_param=new Object[residues];
256
257     for(int i=0;i<residues;i++){
258       residue_type[i]=opb.read(16);
259       if(residue_type[i]<0 || residue_type[i]>=VI_RESB){
260 //      goto err_out;
261         clear();
262         return(-1);
263       }
264       residue_param[i]=FuncResidue.residue_P[residue_type[i]].unpack(this,opb);
265       if(residue_param[i]==null){
266 //      goto err_out;
267         clear();
268         return(-1);
269       }
270     }
271
272     // map backend settings
273     maps=opb.read(6)+1;
274     if(map_type==null || map_type.length!=maps)  map_type=new int[maps];
275     if(map_param==null || map_param.length!=maps)  map_param=new Object[maps];
276     for(int i=0;i<maps;i++){
277       map_type[i]=opb.read(16);
278       if(map_type[i]<0 || map_type[i]>=VI_MAPB){
279 //      goto err_out;
280         clear();
281         return(-1);
282       }
283       map_param[i]=FuncMapping.mapping_P[map_type[i]].unpack(this,opb);
284       if(map_param[i]==null){
285 //    goto err_out;
286         clear();
287         return(-1);
288       }
289     }
290
291   // mode settings
292     modes=opb.read(6)+1;
293     if(mode_param==null || mode_param.length!=modes)
294       mode_param=new InfoMode[modes];
295     for(int i=0;i<modes;i++){
296       mode_param[i]=new InfoMode();
297       mode_param[i].blockflag=opb.read(1);
298       mode_param[i].windowtype=opb.read(16);
299       mode_param[i].transformtype=opb.read(16);
300       mode_param[i].mapping=opb.read(8);
301
302       if((mode_param[i].windowtype>=VI_WINDOWB)||
303          (mode_param[i].transformtype>=VI_WINDOWB)||
304          (mode_param[i].mapping>=maps)){
305 //      goto err_out;
306         clear();
307         return(-1);
308       }
309     }
310
311     if(opb.read(1)!=1){
312     //goto err_out; // top level EOP check
313       clear();
314       return(-1);
315     }
316
317     return(0);
318 // err_out:
319 //  vorbis_info_clear(vi);
320 //  return(-1);
321   }
322
323   // The Vorbis header is in three packets; the initial small packet in
324   // the first page that identifies basic parameters, a second packet
325   // with bitstream comments and a third packet that holds the
326   // codebook.
327
328   public int synthesis_headerin(Comment vc, Packet op){
329     Buffer opb=new Buffer();
330
331     if(op!=null){  
332       opb.readinit(op.packet_base, op.packet, op.bytes);
333
334       // Which of the three types of header is this?
335       // Also verify header-ness, vorbis
336       {
337         byte[] buffer=new byte[6];
338         int packtype=opb.read(8);
339         //memset(buffer,0,6);
340         opb.read(buffer,6);
341         if(buffer[0]!='v' || buffer[1]!='o' || buffer[2]!='r' ||
342            buffer[3]!='b' || buffer[4]!='i' || buffer[5]!='s'){
343         // not a vorbis header
344           return(-1);
345         }
346         switch(packtype){
347         case 0x01: // least significant *bit* is read first
348           if(op.b_o_s==0){
349             // Not the initial packet
350             return(-1);
351           }
352           if(rate!=0){
353             // previously initialized info header
354             return(-1);
355           }
356           return(unpack_info(opb));
357         case 0x03: // least significant *bit* is read first
358           if(rate==0){
359             // um... we didn't get the initial header
360             return(-1);
361           }
362           return(vc.unpack(opb));
363         case 0x05: // least significant *bit* is read first
364           if(rate==0 || vc.vendor==null){
365             // um... we didn;t get the initial header or comments yet
366             return(-1);
367           }
368           return(unpack_books(opb));
369         default:
370           // Not a valid vorbis header type
371           //return(-1);
372           break;
373         }
374       }
375     }
376     return(-1);
377   }
378
379   // pack side
380   int pack_info(Buffer opb){
381     // preamble
382     opb.write(0x01,8);
383     opb.write(_vorbis);
384
385     // basic information about the stream
386     opb.write(0x00,32);
387     opb.write(channels,8);
388     opb.write(rate,32);
389
390     opb.write(bitrate_upper,32);
391     opb.write(bitrate_nominal,32);
392     opb.write(bitrate_lower,32);
393
394     opb.write(ilog2(blocksizes[0]),4);
395     opb.write(ilog2(blocksizes[1]),4);
396     opb.write(1,1);
397     return(0);
398   }
399
400   int pack_books(Buffer opb){
401     opb.write(0x05,8);
402     opb.write(_vorbis);
403
404     // books
405     opb.write(books-1,8);
406     for(int i=0;i<books;i++){
407       if(book_param[i].pack(opb)!=0){
408         //goto err_out;
409         return(-1);
410       }
411     }
412
413     // times
414     opb.write(times-1,6);
415     for(int i=0;i<times;i++){
416       opb.write(time_type[i],16);
417       FuncTime.time_P[time_type[i]].pack(this.time_param[i],opb);
418     }
419
420     // floors
421     opb.write(floors-1,6);
422     for(int i=0;i<floors;i++){
423       opb.write(floor_type[i],16);
424       FuncFloor.floor_P[floor_type[i]].pack(floor_param[i],opb);
425     }
426
427     // residues
428     opb.write(residues-1,6);
429     for(int i=0;i<residues;i++){
430       opb.write(residue_type[i],16);
431       FuncResidue.residue_P[residue_type[i]].pack(residue_param[i],opb);
432     }
433     
434     // maps
435     opb.write(maps-1,6);
436     for(int i=0;i<maps;i++){
437       opb.write(map_type[i],16);
438       FuncMapping.mapping_P[map_type[i]].pack(this,map_param[i],opb);
439     }
440
441     // modes
442     opb.write(modes-1,6);
443     for(int i=0;i<modes;i++){
444       opb.write(mode_param[i].blockflag,1);
445       opb.write(mode_param[i].windowtype,16);
446       opb.write(mode_param[i].transformtype,16);
447       opb.write(mode_param[i].mapping,8);
448     }
449     opb.write(1,1);
450     return(0);
451   //err_out:
452     //return(-1);
453   } 
454
455 //  static void v_writestring(Buffer o, byte[] s){
456 //    int i=0;
457 //    while(s[i]!=0){
458 //      o.write(s[i++],8);
459 //    }
460 //  }
461
462 //  static void v_readstring(Buffer o, byte[] buf, int bytes){
463 //    int i=0
464 //    while(bytes--!=0){
465 //      buf[i++]=o.read(8);
466 //    }
467 //  }
468
469 //  private Buffer opb_blocksize=new Buffer();
470   public int blocksize(Packet op){
471     //codec_setup_info     *ci=vi->codec_setup;
472     Buffer opb=new Buffer();
473 //    synchronized(opb_blocksize){
474     int mode;
475  
476     opb.readinit(op.packet_base, op.packet, op.bytes);
477
478   /* Check the packet type */
479     if(opb.read(1)!=0){
480       /* Oops.  This is not an audio data packet */
481       return(OV_ENOTAUDIO);
482     }
483     {  
484       int modebits=0;
485       int v=modes;
486       while(v>1){
487         modebits++;
488         v>>>=1;
489       }
490
491     /* read our mode and pre/post windowsize */
492       mode=opb.read(modebits);
493     }
494     if(mode==-1)return(OV_EBADPACKET);
495     return(blocksizes[mode_param[mode].blockflag]);
496 //    }
497   }
498
499   private static int ilog2(int v){
500     int ret=0;
501     while(v>1){
502       ret++;
503       v>>>=1;
504     }
505     return(ret);
506   }
507
508   public String toString(){
509     return "version:"+new Integer(version)+
510            ", channels:"+new Integer(channels)+
511            ", rate:"+new Integer(rate)+
512            ", bitrate:"+new Integer(bitrate_upper)+","+
513                         new Integer(bitrate_nominal)+","+
514                         new Integer(bitrate_lower);
515   }
516 }
This page took 0.045778 seconds and 4 git commands to generate.