more changes.
[IRC.git] / Robust / src / Tests / ssJava / mp3decoder / Header.java
1 /*\r
2  * 11/19/04 : 1.0 moved to LGPL.\r
3  *            VBRI header support added, E.B javalayer@javazoom.net\r
4  * \r
5  * 12/04/03 : VBR (XING) header support added, E.B javalayer@javazoom.net\r
6  *\r
7  * 02/13/99 : Java Conversion by JavaZOOM , E.B javalayer@javazoom.net\r
8  *\r
9  * Declarations for MPEG header class\r
10  * A few layer III, MPEG-2 LSF, and seeking modifications made by Jeff Tsay.\r
11  * Last modified : 04/19/97\r
12  *\r
13  *  @(#) header.h 1.7, last edit: 6/15/94 16:55:33\r
14  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)\r
15  *  @(#) Berlin University of Technology\r
16  *-----------------------------------------------------------------------\r
17  *   This program is free software; you can redistribute it and/or modify\r
18  *   it under the terms of the GNU Library General Public License as published\r
19  *   by the Free Software Foundation; either version 2 of the License, or\r
20  *   (at your option) any later version.\r
21  *\r
22  *   This program is distributed in the hope that it will be useful,\r
23  *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
24  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
25  *   GNU Library General Public License for more details.\r
26  *\r
27  *   You should have received a copy of the GNU Library General Public\r
28  *   License along with this program; if not, write to the Free Software\r
29  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
30  *----------------------------------------------------------------------\r
31  */\r
32 \r
33 /**\r
34  * Class for extracting information from a frame header.\r
35  */\r
36 @LATTICE("HI<HNS,HNS<H,C<H,NS<FS,FS<H,FS<HV,H<SYNC,HV<SYNC,HV<T,SYNC*,HV*,FS*,HI*")\r
37 @METHODDEFAULT("OUT<V,V<THIS,THIS<SH,SH<IN,SH*,THISLOC=THIS,GLOBALLOC=IN")\r
38 public final class Header\r
39 {\r
40         @LOC("T") public  static final int[][]  frequencies =\r
41                                                 {{22050, 24000, 16000, 1},\r
42                                                 {44100, 48000, 32000, 1},\r
43                                                 {11025, 12000, 8000, 1}};       // SZD: MPEG25\r
44 \r
45         /**\r
46          * Constant for MPEG-2 LSF version\r
47          */\r
48         @LOC("T") public static final int               MPEG2_LSF = 0;\r
49         @LOC("T") public static final int               MPEG25_LSF = 2; // SZD\r
50 \r
51         /**\r
52          * Constant for MPEG-1 version\r
53          */\r
54         @LOC("T") public static final int               MPEG1 = 1;\r
55 \r
56         @LOC("T") public static final int               STEREO = 0;\r
57         @LOC("T") public static final int               JOINT_STEREO = 1;\r
58         @LOC("T") public static final int               DUAL_CHANNEL = 2;\r
59         @LOC("T") public static final int               SINGLE_CHANNEL = 3;\r
60         @LOC("T") public static final int               FOURTYFOUR_POINT_ONE = 0;\r
61         @LOC("T") public static final int               FOURTYEIGHT=1;\r
62         @LOC("T") public static final int               THIRTYTWO=2;\r
63 \r
64     @LOC("H") private int                               h_layer;\r
65     @LOC("H") private int  h_protection_bit;\r
66     @LOC("H") private int h_bitrate_index;\r
67     @LOC("H") private int h_padding_bit;\r
68     @LOC("H") private int h_mode_extension;\r
69     @LOC("HV") private int                              h_version;\r
70     @LOC("H") private int                               h_mode;\r
71     @LOC("H") private int                               h_sample_frequency;\r
72     @LOC("HNS") private int                             h_number_of_subbands;\r
73     @LOC("HI") private int h_intensity_stereo_bound;\r
74     @LOC("H") private boolean                   h_copyright;\r
75     @LOC("H") private boolean h_original;\r
76         // VBR support added by E.B\r
77     @LOC("T") private double[]          h_vbr_time_per_frame = {-1.0, 384.0, 1152.0, 1152.0};\r
78     @LOC("T") private boolean                   h_vbr;\r
79     @LOC("T") private int                               h_vbr_frames;\r
80     @LOC("T") private int                               h_vbr_scale;\r
81     @LOC("T") private int                               h_vbr_bytes;\r
82     @LOC("T") private byte[]                    h_vbr_toc;\r
83         \r
84     @LOC("SYNC") private byte                   syncmode = Bitstream.INITIAL_SYNC;\r
85     @LOC("C") private Crc16                     crc;\r
86 \r
87     @LOC("C") public short                      checksum;\r
88     @LOC("FS") public int                               framesize;\r
89     @LOC("NS") public int                               nSlots;\r
90 \r
91     @LOC("T") private int                               _headerstring = -1; // E.B\r
92 \r
93         Header()\r
94         {\r
95         }\r
96         public String toString()\r
97         {\r
98                 StringBuffer buffer = new StringBuffer(200);\r
99                 buffer.append("Layer ");\r
100                 buffer.append(layer_string());\r
101                 buffer.append(" frame ");\r
102                 buffer.append(mode_string());\r
103                 buffer.append(' ');\r
104                 buffer.append(version_string());\r
105                 if (!checksums())\r
106                         buffer.append(" no");\r
107                 buffer.append(" checksums");\r
108                 buffer.append(' ');\r
109                 buffer.append(sample_frequency_string());\r
110                 buffer.append(',');\r
111                 buffer.append(' ');\r
112                 buffer.append(bitrate_string());\r
113 \r
114                 String s =  buffer.toString();\r
115                 return s;\r
116         }\r
117 \r
118         /**\r
119          * Read a 32-bit header from the bitstream.\r
120          */\r
121         void read_header(Bitstream stream, Crc16[] crcp) throws BitstreamException\r
122         {\r
123                 int headerstring;\r
124                 int channel_bitrate;\r
125                 boolean sync = false;\r
126                 do\r
127                 {\r
128                         headerstring = stream.syncHeader(syncmode);\r
129                         _headerstring = headerstring; // E.B\r
130                         if (syncmode == Bitstream.INITIAL_SYNC)\r
131                         {\r
132                                 h_version = ((headerstring >>> 19) & 1);\r
133                                 if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection\r
134                                         if (h_version == MPEG2_LSF)\r
135                                                 h_version = MPEG25_LSF;\r
136                                         else\r
137                                                 throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);\r
138                                 if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3)\r
139                                 {\r
140                                         throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);\r
141                                 }\r
142                         }\r
143                         h_layer = 4 - (headerstring >>> 17) & 3;\r
144                         h_protection_bit = (headerstring >>> 16) & 1;\r
145                         h_bitrate_index = (headerstring >>> 12) & 0xF;\r
146                         h_padding_bit = (headerstring >>> 9) & 1;\r
147                         h_mode = ((headerstring >>> 6) & 3);\r
148                         h_mode_extension = (headerstring >>> 4) & 3;\r
149                         if (h_mode == JOINT_STEREO)\r
150                                 h_intensity_stereo_bound = (h_mode_extension << 2) + 4;\r
151                         else\r
152                                 h_intensity_stereo_bound = 0; // should never be used\r
153                         if (((headerstring >>> 3) & 1) == 1)\r
154                                 h_copyright = true;\r
155                         if (((headerstring >>> 2) & 1) == 1)\r
156                                 h_original = true;\r
157                         // calculate number of subbands:\r
158                         if (h_layer == 1)\r
159                                 h_number_of_subbands = 32;\r
160                         else\r
161                         {\r
162                                 channel_bitrate = h_bitrate_index;\r
163                                 // calculate bitrate per channel:\r
164                                 if (h_mode != SINGLE_CHANNEL)\r
165                                         if (channel_bitrate == 4)\r
166                                                 channel_bitrate = 1;\r
167                                         else\r
168                                                 channel_bitrate -= 4;\r
169                                 if ((channel_bitrate == 1) || (channel_bitrate == 2))\r
170                                         if (h_sample_frequency == THIRTYTWO)\r
171                                                 h_number_of_subbands = 12;\r
172                                         else\r
173                                                 h_number_of_subbands = 8;\r
174                                 else if ((h_sample_frequency == FOURTYEIGHT) || ((channel_bitrate >= 3) && (channel_bitrate <= 5)))\r
175                                         h_number_of_subbands = 27;\r
176                                 else\r
177                                         h_number_of_subbands = 30;\r
178                         }\r
179                         if (h_intensity_stereo_bound > h_number_of_subbands)\r
180                                 h_intensity_stereo_bound = h_number_of_subbands;\r
181                         // calculate framesize and nSlots\r
182                         calculate_framesize();\r
183                         // read framedata:\r
184                         int framesizeloaded = stream.read_frame_data(framesize);\r
185                         if ((framesize >=0) && (framesizeloaded != framesize))\r
186                         {\r
187                                 // Data loaded does not match to expected framesize,\r
188                                 // it might be an ID3v1 TAG. (Fix 11/17/04).\r
189                                 throw stream.newBitstreamException(Bitstream.INVALIDFRAME);\r
190                         }\r
191                         if (stream.isSyncCurrentPosition(syncmode))\r
192                         {\r
193                                 if (syncmode == Bitstream.INITIAL_SYNC)\r
194                                 {\r
195                                         syncmode = Bitstream.STRICT_SYNC;\r
196                                         stream.set_syncword(headerstring & 0xFFF80CC0);\r
197                                 }\r
198                                 sync = true;\r
199                         }\r
200                         else\r
201                         {\r
202                                 stream.unreadFrame();\r
203                         }\r
204                 }\r
205                 while (!sync);\r
206                 stream.parse_frame();\r
207                 if (h_protection_bit == 0)\r
208                 {\r
209                         // frame contains a crc checksum\r
210                         checksum = (short) stream.get_bits(16);\r
211                         if (crc == null)\r
212                                 crc = new Crc16();\r
213                         crc.add_bits(headerstring, 16);\r
214                         crcp[0] = crc;\r
215                 }\r
216                 else\r
217                         crcp[0] = null;\r
218                 if (h_sample_frequency == FOURTYFOUR_POINT_ONE)\r
219                 {\r
220                         /*\r
221                                 if (offset == null)\r
222                           {\r
223                                   int max = max_number_of_frames(stream);\r
224                                   offset = new int[max];\r
225                              for(int i=0; i<max; i++) offset[i] = 0;\r
226                           }\r
227                           // E.B : Investigate more\r
228                           int cf = stream.current_frame();\r
229                           int lf = stream.last_frame();\r
230                           if ((cf > 0) && (cf == lf))\r
231                           {\r
232                                    offset[cf] = offset[cf-1] + h_padding_bit;\r
233                           }\r
234                           else\r
235                           {\r
236                                        offset[0] = h_padding_bit;\r
237                           }\r
238                         */\r
239                 }\r
240         }\r
241 \r
242         /**\r
243          * Parse frame to extract optionnal VBR frame.\r
244          * @param firstframe\r
245          * @author E.B (javalayer@javazoom.net)\r
246          */\r
247         void parseVBR(byte[] firstframe) throws BitstreamException\r
248         {\r
249                 // Trying Xing header.\r
250                 String xing = "Xing";\r
251                 byte tmp[] = new byte[4];\r
252                 int offset = 0;\r
253                 // Compute "Xing" offset depending on MPEG version and channels.\r
254                 if (h_version == MPEG1) \r
255                 {\r
256                   if (h_mode == SINGLE_CHANNEL)  offset=21-4;\r
257                   else offset=36-4;\r
258                 } \r
259                 else \r
260                 {\r
261                   if (h_mode == SINGLE_CHANNEL) offset=13-4;\r
262                   else offset = 21-4;             \r
263                 }\r
264                 try\r
265                 {\r
266                         System.arraycopy(firstframe, offset, tmp, 0, 4);\r
267                         // Is "Xing" ?\r
268                         if (xing.equals(new String(tmp)))\r
269                         {\r
270                                 //Yes.\r
271                                 h_vbr = true;\r
272                                 h_vbr_frames = -1;\r
273                                 h_vbr_bytes = -1;\r
274                                 h_vbr_scale = -1;\r
275                                 h_vbr_toc = new byte[100];\r
276                                                                 \r
277                                 int length = 4;\r
278                                 // Read flags.\r
279                                 byte flags[] = new byte[4];\r
280                                 System.arraycopy(firstframe, offset + length, flags, 0, flags.length);\r
281                                 length += flags.length;\r
282                                 // Read number of frames (if available).\r
283                                 if ((flags[3] & (byte) (1 << 0)) != 0)\r
284                                 {\r
285                                         System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
286                                         h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;\r
287                                         length += 4;    \r
288                                 }\r
289                                 // Read size (if available).\r
290                                 if ((flags[3] & (byte) (1 << 1)) != 0)\r
291                                 {\r
292                                         System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
293                                         h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;\r
294                                         length += 4;    \r
295                                 }\r
296                                 // Read TOC (if available).\r
297                                 if ((flags[3] & (byte) (1 << 2)) != 0)\r
298                                 {\r
299                                         System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length);\r
300                                         length += h_vbr_toc.length;     \r
301                                 }\r
302                                 // Read scale (if available).\r
303                                 if ((flags[3] & (byte) (1 << 3)) != 0)\r
304                                 {\r
305                                         System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
306                                         h_vbr_scale = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;\r
307                                         length += 4;    \r
308                                 }\r
309                                 //System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes);                       \r
310                         }                               \r
311                 }\r
312                 catch (ArrayIndexOutOfBoundsException e)\r
313                 {\r
314                         throw new BitstreamException("XingVBRHeader Corrupted",e);\r
315                 }\r
316                 \r
317                 // Trying VBRI header.                  \r
318                 String vbri = "VBRI";\r
319                 offset = 36-4;\r
320                 try\r
321                 {\r
322                         System.arraycopy(firstframe, offset, tmp, 0, 4);\r
323                         // Is "VBRI" ?\r
324                         if (vbri.equals(new String(tmp)))\r
325                         {\r
326                                 //Yes.\r
327                                 h_vbr = true;\r
328                                 h_vbr_frames = -1;\r
329                                 h_vbr_bytes = -1;\r
330                                 h_vbr_scale = -1;\r
331                                 h_vbr_toc = new byte[100];\r
332                                 // Bytes.                               \r
333                                 int length = 4 + 6;\r
334                                 System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
335                                 h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;\r
336                                 length += 4;    \r
337                                 // Frames.      \r
338                                 System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
339                                 h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;\r
340                                 length += 4;    \r
341                                 //System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes);\r
342                                 // TOC\r
343                                 // TODO                         \r
344                         }\r
345                 }\r
346                 catch (ArrayIndexOutOfBoundsException e)\r
347                 {\r
348                         throw new BitstreamException("VBRIVBRHeader Corrupted",e);\r
349                 }\r
350         }\r
351         \r
352         // Functions to query header contents:\r
353         /**\r
354          * Returns version.\r
355          */\r
356      @RETURNLOC("OUT")\r
357         public int version() { return h_version; }\r
358 \r
359         /**\r
360          * Returns Layer ID.\r
361          */\r
362         @RETURNLOC("OUT")\r
363         public int layer() { return h_layer; }\r
364 \r
365         /**\r
366          * Returns bitrate index.\r
367          */\r
368         @RETURNLOC("OUT")\r
369         public int bitrate_index() { return h_bitrate_index; }\r
370 \r
371         /**\r
372          * Returns Sample Frequency.\r
373          */\r
374         public int sample_frequency() { return h_sample_frequency; }\r
375 \r
376         /**\r
377          * Returns Frequency.\r
378          */\r
379         public int frequency() {return frequencies[h_version][h_sample_frequency];}\r
380 \r
381         /**\r
382          * Returns Mode.\r
383          */\r
384         @RETURNLOC("OUT")\r
385         public int mode() { return h_mode; }\r
386 \r
387         /**\r
388          * Returns Protection bit.\r
389          */\r
390         public boolean checksums()\r
391         {\r
392                 if (h_protection_bit == 0) return true;\r
393           else return false;\r
394         }\r
395 \r
396         /**\r
397          * Returns Copyright.\r
398          */\r
399         public boolean copyright() { return h_copyright; }\r
400 \r
401         /**\r
402          * Returns Original.\r
403          */\r
404         public boolean original() { return h_original; }\r
405 \r
406         /**\r
407          * Return VBR.\r
408          * @return true if VBR header is found\r
409          */\r
410         public boolean vbr() { return h_vbr; }\r
411 \r
412         /**\r
413          * Return VBR scale.\r
414          * @return scale of -1 if not available\r
415          */\r
416         public int vbr_scale() { return h_vbr_scale; }\r
417 \r
418         /**\r
419          * Return VBR TOC.\r
420          * @return vbr toc ot null if not available\r
421          */\r
422         public byte[] vbr_toc() { return h_vbr_toc; }\r
423 \r
424         /**\r
425          * Returns Checksum flag.\r
426          * Compares computed checksum with stream checksum.\r
427          */\r
428         @RETURNLOC("OUT")\r
429         public boolean checksum_ok () { return (checksum == crc.checksum()); }\r
430 \r
431         // Seeking and layer III stuff\r
432         /**\r
433          * Returns Layer III Padding bit.\r
434          */\r
435         public boolean padding()\r
436         {\r
437                 if (h_padding_bit == 0) return false;\r
438           else return true;\r
439         }\r
440 \r
441         /**\r
442          * Returns Slots.\r
443          */\r
444         @RETURNLOC("OUT")\r
445         public int slots() { return nSlots; }\r
446 \r
447         /**\r
448          * Returns Mode Extension.\r
449          */\r
450         @RETURNLOC("OUT")\r
451         public int mode_extension() { return h_mode_extension; }\r
452 \r
453         // E.B -> private to public\r
454     @LOC("T") public static final int bitrates[][][] = {\r
455                 {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,\r
456           112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0},\r
457                 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
458           56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},\r
459                 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
460           56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}},\r
461 \r
462                 {{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000,\r
463            224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0},\r
464           {0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,\r
465            112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0},\r
466           {0 /*free format*/, 32000, 40000, 48000, 56000, 64000, 80000,\r
467            96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}},\r
468                 // SZD: MPEG2.5\r
469                 {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,\r
470           112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0},\r
471                 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
472           56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},\r
473                 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
474           56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}},\r
475 \r
476                 };\r
477 \r
478         // E.B -> private to public\r
479         /**\r
480          * Calculate Frame size.\r
481          * Calculates framesize in bytes excluding header size.\r
482          */\r
483         public int calculate_framesize()\r
484         {\r
485 \r
486          if (h_layer == 1)\r
487          {\r
488            framesize = (12 * bitrates[h_version][0][h_bitrate_index]) /\r
489                        frequencies[h_version][h_sample_frequency];\r
490            if (h_padding_bit != 0 ) framesize++;\r
491            framesize <<= 2;             // one slot is 4 bytes long\r
492            nSlots = 0;\r
493          }\r
494          else\r
495          {\r
496            framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) /\r
497                        frequencies[h_version][h_sample_frequency];\r
498            if (h_version == MPEG2_LSF || h_version == MPEG25_LSF) framesize >>= 1;      // SZD\r
499            if (h_padding_bit != 0) framesize++;\r
500            // Layer III slots\r
501            if (h_layer == 3)\r
502            {\r
503              if (h_version == MPEG1)\r
504              {\r
505                          nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side info size\r
506                                                                           -  ((h_protection_bit!=0) ? 0 : 2)                   // CRC size\r
507                                                                           - 4;                                                                       // header size\r
508              }\r
509              else\r
510                  {  // MPEG-2 LSF, SZD: MPEG-2.5 LSF\r
511                 nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ?  9 : 17) // side info size\r
512                                                                   -  ((h_protection_bit!=0) ? 0 : 2)                   // CRC size\r
513                                                                           - 4;                                                                       // header size\r
514              }\r
515            }\r
516            else\r
517            {\r
518                  nSlots = 0;\r
519            }\r
520          }\r
521          framesize -= 4;             // subtract header size\r
522          return framesize;\r
523         }\r
524 \r
525         /**\r
526          * Returns the maximum number of frames in the stream.\r
527          * @param streamsize\r
528          * @return number of frames\r
529          */\r
530         public int max_number_of_frames(int streamsize)  // E.B\r
531         {\r
532                 if (h_vbr == true) return h_vbr_frames;\r
533                 else\r
534                 {\r
535                         if ((framesize + 4 - h_padding_bit) == 0) return 0;\r
536                         else return(streamsize / (framesize + 4 - h_padding_bit));\r
537                 }\r
538         }\r
539 \r
540         /**\r
541          * Returns the maximum number of frames in the stream.\r
542          * @param streamsize\r
543          * @return number of frames\r
544          */\r
545         public int min_number_of_frames(int streamsize) // E.B\r
546         {\r
547                 if (h_vbr == true) return h_vbr_frames;\r
548                 else\r
549                 {\r
550                         if ((framesize + 5 - h_padding_bit) == 0) return 0;\r
551                         else return(streamsize / (framesize + 5 - h_padding_bit));\r
552                 }\r
553         }\r
554 \r
555 \r
556         /**\r
557          * Returns ms/frame.\r
558          * @return milliseconds per frame\r
559          */\r
560         public float ms_per_frame() // E.B\r
561         {\r
562                 if (h_vbr == true)\r
563                 {                       \r
564                         double tpf = h_vbr_time_per_frame[layer()] / frequency();\r
565                         if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF)) tpf /= 2;\r
566                         return ((float) (tpf * 1000));\r
567                 }\r
568                 else\r
569                 {\r
570                         float ms_per_frame_array[][] = {{8.707483f,  8.0f, 12.0f},\r
571                                                                                         {26.12245f, 24.0f, 36.0f},\r
572                                                                                         {26.12245f, 24.0f, 36.0f}};\r
573                         return(ms_per_frame_array[h_layer-1][h_sample_frequency]);\r
574                 }\r
575         }\r
576 \r
577         /**\r
578          * Returns total ms.\r
579          * @param streamsize\r
580          * @return total milliseconds\r
581          */\r
582         public float total_ms(int streamsize) // E.B\r
583         {\r
584                 return(max_number_of_frames(streamsize) * ms_per_frame());\r
585         }\r
586 \r
587         /**\r
588          * Returns synchronized header.\r
589          */\r
590         public int getSyncHeader() // E.B\r
591         {\r
592                 return _headerstring;\r
593         }\r
594 \r
595         // functions which return header informations as strings:\r
596         /**\r
597          * Return Layer version.\r
598          */\r
599         public String layer_string()\r
600         {\r
601                 switch (h_layer)\r
602                 {\r
603            case 1:\r
604                 return "I";\r
605            case 2:\r
606                 return "II";\r
607            case 3:\r
608                 return "III";\r
609                 }\r
610           return null;\r
611         }\r
612 \r
613         // E.B -> private to public\r
614     @LOC("T") public static final String bitrate_str[][][] = {\r
615                 {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
616           "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s",\r
617           "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s",\r
618           "forbidden"},\r
619           {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
620           "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
621           "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
622           "forbidden"},\r
623           {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
624           "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
625           "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
626           "forbidden"}},\r
627 \r
628           {{"free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s",\r
629           "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s",\r
630           "320 kbit/s", "352 kbit/s", "384 kbit/s", "416 kbit/s", "448 kbit/s",\r
631           "forbidden"},\r
632           {"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
633           "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s",\r
634           "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "384 kbit/s",\r
635           "forbidden"},\r
636           {"free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s",\r
637           "64 kbit/s", "80 kbit/s" , "96 kbit/s", "112 kbit/s", "128 kbit/s",\r
638           "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s",\r
639           "forbidden"}},\r
640                 // SZD: MPEG2.5\r
641                 {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
642           "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s",\r
643           "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s",\r
644           "forbidden"},\r
645           {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
646           "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
647           "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
648           "forbidden"},\r
649           {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
650           "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
651           "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
652           "forbidden"}},\r
653           };\r
654 \r
655         /**\r
656          * Return Bitrate.\r
657          * @return bitrate in bps\r
658          */\r
659         public String bitrate_string()\r
660         {\r
661                 if (h_vbr == true)\r
662                 {\r
663                         return Integer.toString(bitrate()/1000)+" kb/s";                \r
664                 }\r
665           else return bitrate_str[h_version][h_layer - 1][h_bitrate_index];\r
666         }\r
667 \r
668         /**\r
669          * Return Bitrate.\r
670          * @return bitrate in bps and average bitrate for VBR header\r
671          */\r
672         public int bitrate()\r
673         {\r
674                 if (h_vbr == true)\r
675                 {\r
676                         return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames)))*1000;              \r
677                 }\r
678                 else return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
679         }\r
680 \r
681         /**\r
682          * Return Instant Bitrate.\r
683          * Bitrate for VBR is not constant.\r
684          * @return bitrate in bps\r
685          */\r
686         public int bitrate_instant()\r
687         {\r
688                 return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
689         }\r
690 \r
691         /**\r
692          * Returns Frequency\r
693          * @return frequency string in kHz\r
694          */\r
695         public String sample_frequency_string()\r
696         {\r
697                 switch (h_sample_frequency)\r
698                 {\r
699             case THIRTYTWO:\r
700                 if (h_version == MPEG1)\r
701                         return "32 kHz";\r
702                 else if (h_version == MPEG2_LSF)\r
703                 return "16 kHz";\r
704             else        // SZD\r
705                 return "8 kHz";\r
706             case FOURTYFOUR_POINT_ONE:\r
707                 if (h_version == MPEG1)\r
708                         return "44.1 kHz";\r
709                 else if (h_version == MPEG2_LSF)\r
710                 return "22.05 kHz";\r
711                 else    // SZD\r
712                 return "11.025 kHz";\r
713             case FOURTYEIGHT:\r
714                 if (h_version == MPEG1)\r
715                         return "48 kHz";\r
716                 else if (h_version == MPEG2_LSF)\r
717                 return "24 kHz";\r
718                 else    // SZD\r
719                         return "12 kHz";\r
720           }\r
721           return(null);\r
722         }\r
723 \r
724         /**\r
725          * Returns Mode.\r
726          */\r
727         public String mode_string()\r
728         {\r
729            switch (h_mode)\r
730            {\r
731              case STEREO:\r
732                 return "Stereo";\r
733              case JOINT_STEREO:\r
734                 return "Joint stereo";\r
735              case DUAL_CHANNEL:\r
736                 return "Dual channel";\r
737              case SINGLE_CHANNEL:\r
738                 return "Single channel";\r
739            }\r
740            return null;\r
741         }\r
742 \r
743         /**\r
744          * Returns Version.\r
745          * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF\r
746          */\r
747         public String version_string()\r
748         {\r
749           switch (h_version)\r
750           {\r
751             case MPEG1:\r
752               return "MPEG-1";\r
753             case MPEG2_LSF:\r
754               return "MPEG-2 LSF";\r
755             case MPEG25_LSF:    // SZD\r
756               return "MPEG-2.5 LSF";\r
757           }\r
758           return(null);\r
759         }\r
760 \r
761         /**\r
762          * Returns the number of subbands in the current frame.\r
763          * @return number of subbands\r
764          */\r
765         @RETURNLOC("OUT")\r
766         public int number_of_subbands() {return h_number_of_subbands;}\r
767 \r
768         /**\r
769          * Returns Intensity Stereo.\r
770          * (Layer II joint stereo only).\r
771          * Returns the number of subbands which are in stereo mode,\r
772          * subbands above that limit are in intensity stereo mode.\r
773          * @return intensity\r
774          */\r
775         @RETURNLOC("OUT")\r
776         public int intensity_stereo_bound() {return h_intensity_stereo_bound;}\r
777 }\r