adding more annotations for mp3decoder
[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         public int version() { return h_version; }\r
357 \r
358         /**\r
359          * Returns Layer ID.\r
360          */\r
361         @RETURNLOC("THIS")\r
362         public int layer() { return h_layer; }\r
363 \r
364         /**\r
365          * Returns bitrate index.\r
366          */\r
367         public int bitrate_index() { return h_bitrate_index; }\r
368 \r
369         /**\r
370          * Returns Sample Frequency.\r
371          */\r
372         public int sample_frequency() { return h_sample_frequency; }\r
373 \r
374         /**\r
375          * Returns Frequency.\r
376          */\r
377         public int frequency() {return frequencies[h_version][h_sample_frequency];}\r
378 \r
379         /**\r
380          * Returns Mode.\r
381          */\r
382         public int mode() { return h_mode; }\r
383 \r
384         /**\r
385          * Returns Protection bit.\r
386          */\r
387         public boolean checksums()\r
388         {\r
389                 if (h_protection_bit == 0) return true;\r
390           else return false;\r
391         }\r
392 \r
393         /**\r
394          * Returns Copyright.\r
395          */\r
396         public boolean copyright() { return h_copyright; }\r
397 \r
398         /**\r
399          * Returns Original.\r
400          */\r
401         public boolean original() { return h_original; }\r
402 \r
403         /**\r
404          * Return VBR.\r
405          * @return true if VBR header is found\r
406          */\r
407         public boolean vbr() { return h_vbr; }\r
408 \r
409         /**\r
410          * Return VBR scale.\r
411          * @return scale of -1 if not available\r
412          */\r
413         public int vbr_scale() { return h_vbr_scale; }\r
414 \r
415         /**\r
416          * Return VBR TOC.\r
417          * @return vbr toc ot null if not available\r
418          */\r
419         public byte[] vbr_toc() { return h_vbr_toc; }\r
420 \r
421         /**\r
422          * Returns Checksum flag.\r
423          * Compares computed checksum with stream checksum.\r
424          */\r
425         public boolean checksum_ok () { return (checksum == crc.checksum()); }\r
426 \r
427         // Seeking and layer III stuff\r
428         /**\r
429          * Returns Layer III Padding bit.\r
430          */\r
431         public boolean padding()\r
432         {\r
433                 if (h_padding_bit == 0) return false;\r
434           else return true;\r
435         }\r
436 \r
437         /**\r
438          * Returns Slots.\r
439          */\r
440         public int slots() { return nSlots; }\r
441 \r
442         /**\r
443          * Returns Mode Extension.\r
444          */\r
445         public int mode_extension() { return h_mode_extension; }\r
446 \r
447         // E.B -> private to public\r
448     @LOC("T") public static final int bitrates[][][] = {\r
449                 {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,\r
450           112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0},\r
451                 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
452           56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},\r
453                 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
454           56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}},\r
455 \r
456                 {{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000,\r
457            224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0},\r
458           {0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,\r
459            112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0},\r
460           {0 /*free format*/, 32000, 40000, 48000, 56000, 64000, 80000,\r
461            96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}},\r
462                 // SZD: MPEG2.5\r
463                 {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,\r
464           112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0},\r
465                 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
466           56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},\r
467                 {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
468           56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}},\r
469 \r
470                 };\r
471 \r
472         // E.B -> private to public\r
473         /**\r
474          * Calculate Frame size.\r
475          * Calculates framesize in bytes excluding header size.\r
476          */\r
477         public int calculate_framesize()\r
478         {\r
479 \r
480          if (h_layer == 1)\r
481          {\r
482            framesize = (12 * bitrates[h_version][0][h_bitrate_index]) /\r
483                        frequencies[h_version][h_sample_frequency];\r
484            if (h_padding_bit != 0 ) framesize++;\r
485            framesize <<= 2;             // one slot is 4 bytes long\r
486            nSlots = 0;\r
487          }\r
488          else\r
489          {\r
490            framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) /\r
491                        frequencies[h_version][h_sample_frequency];\r
492            if (h_version == MPEG2_LSF || h_version == MPEG25_LSF) framesize >>= 1;      // SZD\r
493            if (h_padding_bit != 0) framesize++;\r
494            // Layer III slots\r
495            if (h_layer == 3)\r
496            {\r
497              if (h_version == MPEG1)\r
498              {\r
499                          nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side info size\r
500                                                                           -  ((h_protection_bit!=0) ? 0 : 2)                   // CRC size\r
501                                                                           - 4;                                                                       // header size\r
502              }\r
503              else\r
504                  {  // MPEG-2 LSF, SZD: MPEG-2.5 LSF\r
505                 nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ?  9 : 17) // side info size\r
506                                                                   -  ((h_protection_bit!=0) ? 0 : 2)                   // CRC size\r
507                                                                           - 4;                                                                       // header size\r
508              }\r
509            }\r
510            else\r
511            {\r
512                  nSlots = 0;\r
513            }\r
514          }\r
515          framesize -= 4;             // subtract header size\r
516          return framesize;\r
517         }\r
518 \r
519         /**\r
520          * Returns the maximum number of frames in the stream.\r
521          * @param streamsize\r
522          * @return number of frames\r
523          */\r
524         public int max_number_of_frames(int streamsize)  // E.B\r
525         {\r
526                 if (h_vbr == true) return h_vbr_frames;\r
527                 else\r
528                 {\r
529                         if ((framesize + 4 - h_padding_bit) == 0) return 0;\r
530                         else return(streamsize / (framesize + 4 - h_padding_bit));\r
531                 }\r
532         }\r
533 \r
534         /**\r
535          * Returns the maximum number of frames in the stream.\r
536          * @param streamsize\r
537          * @return number of frames\r
538          */\r
539         public int min_number_of_frames(int streamsize) // E.B\r
540         {\r
541                 if (h_vbr == true) return h_vbr_frames;\r
542                 else\r
543                 {\r
544                         if ((framesize + 5 - h_padding_bit) == 0) return 0;\r
545                         else return(streamsize / (framesize + 5 - h_padding_bit));\r
546                 }\r
547         }\r
548 \r
549 \r
550         /**\r
551          * Returns ms/frame.\r
552          * @return milliseconds per frame\r
553          */\r
554         public float ms_per_frame() // E.B\r
555         {\r
556                 if (h_vbr == true)\r
557                 {                       \r
558                         double tpf = h_vbr_time_per_frame[layer()] / frequency();\r
559                         if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF)) tpf /= 2;\r
560                         return ((float) (tpf * 1000));\r
561                 }\r
562                 else\r
563                 {\r
564                         float ms_per_frame_array[][] = {{8.707483f,  8.0f, 12.0f},\r
565                                                                                         {26.12245f, 24.0f, 36.0f},\r
566                                                                                         {26.12245f, 24.0f, 36.0f}};\r
567                         return(ms_per_frame_array[h_layer-1][h_sample_frequency]);\r
568                 }\r
569         }\r
570 \r
571         /**\r
572          * Returns total ms.\r
573          * @param streamsize\r
574          * @return total milliseconds\r
575          */\r
576         public float total_ms(int streamsize) // E.B\r
577         {\r
578                 return(max_number_of_frames(streamsize) * ms_per_frame());\r
579         }\r
580 \r
581         /**\r
582          * Returns synchronized header.\r
583          */\r
584         public int getSyncHeader() // E.B\r
585         {\r
586                 return _headerstring;\r
587         }\r
588 \r
589         // functions which return header informations as strings:\r
590         /**\r
591          * Return Layer version.\r
592          */\r
593         public String layer_string()\r
594         {\r
595                 switch (h_layer)\r
596                 {\r
597            case 1:\r
598                 return "I";\r
599            case 2:\r
600                 return "II";\r
601            case 3:\r
602                 return "III";\r
603                 }\r
604           return null;\r
605         }\r
606 \r
607         // E.B -> private to public\r
608     @LOC("T") public static final String bitrate_str[][][] = {\r
609                 {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
610           "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s",\r
611           "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s",\r
612           "forbidden"},\r
613           {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
614           "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
615           "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
616           "forbidden"},\r
617           {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
618           "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
619           "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
620           "forbidden"}},\r
621 \r
622           {{"free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s",\r
623           "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s",\r
624           "320 kbit/s", "352 kbit/s", "384 kbit/s", "416 kbit/s", "448 kbit/s",\r
625           "forbidden"},\r
626           {"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
627           "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s",\r
628           "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "384 kbit/s",\r
629           "forbidden"},\r
630           {"free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s",\r
631           "64 kbit/s", "80 kbit/s" , "96 kbit/s", "112 kbit/s", "128 kbit/s",\r
632           "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s",\r
633           "forbidden"}},\r
634                 // SZD: MPEG2.5\r
635                 {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
636           "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s",\r
637           "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s",\r
638           "forbidden"},\r
639           {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
640           "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
641           "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
642           "forbidden"},\r
643           {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
644           "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
645           "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
646           "forbidden"}},\r
647           };\r
648 \r
649         /**\r
650          * Return Bitrate.\r
651          * @return bitrate in bps\r
652          */\r
653         public String bitrate_string()\r
654         {\r
655                 if (h_vbr == true)\r
656                 {\r
657                         return Integer.toString(bitrate()/1000)+" kb/s";                \r
658                 }\r
659           else return bitrate_str[h_version][h_layer - 1][h_bitrate_index];\r
660         }\r
661 \r
662         /**\r
663          * Return Bitrate.\r
664          * @return bitrate in bps and average bitrate for VBR header\r
665          */\r
666         public int bitrate()\r
667         {\r
668                 if (h_vbr == true)\r
669                 {\r
670                         return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames)))*1000;              \r
671                 }\r
672                 else return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
673         }\r
674 \r
675         /**\r
676          * Return Instant Bitrate.\r
677          * Bitrate for VBR is not constant.\r
678          * @return bitrate in bps\r
679          */\r
680         public int bitrate_instant()\r
681         {\r
682                 return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
683         }\r
684 \r
685         /**\r
686          * Returns Frequency\r
687          * @return frequency string in kHz\r
688          */\r
689         public String sample_frequency_string()\r
690         {\r
691                 switch (h_sample_frequency)\r
692                 {\r
693             case THIRTYTWO:\r
694                 if (h_version == MPEG1)\r
695                         return "32 kHz";\r
696                 else if (h_version == MPEG2_LSF)\r
697                 return "16 kHz";\r
698             else        // SZD\r
699                 return "8 kHz";\r
700             case FOURTYFOUR_POINT_ONE:\r
701                 if (h_version == MPEG1)\r
702                         return "44.1 kHz";\r
703                 else if (h_version == MPEG2_LSF)\r
704                 return "22.05 kHz";\r
705                 else    // SZD\r
706                 return "11.025 kHz";\r
707             case FOURTYEIGHT:\r
708                 if (h_version == MPEG1)\r
709                         return "48 kHz";\r
710                 else if (h_version == MPEG2_LSF)\r
711                 return "24 kHz";\r
712                 else    // SZD\r
713                         return "12 kHz";\r
714           }\r
715           return(null);\r
716         }\r
717 \r
718         /**\r
719          * Returns Mode.\r
720          */\r
721         public String mode_string()\r
722         {\r
723            switch (h_mode)\r
724            {\r
725              case STEREO:\r
726                 return "Stereo";\r
727              case JOINT_STEREO:\r
728                 return "Joint stereo";\r
729              case DUAL_CHANNEL:\r
730                 return "Dual channel";\r
731              case SINGLE_CHANNEL:\r
732                 return "Single channel";\r
733            }\r
734            return null;\r
735         }\r
736 \r
737         /**\r
738          * Returns Version.\r
739          * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF\r
740          */\r
741         public String version_string()\r
742         {\r
743           switch (h_version)\r
744           {\r
745             case MPEG1:\r
746               return "MPEG-1";\r
747             case MPEG2_LSF:\r
748               return "MPEG-2 LSF";\r
749             case MPEG25_LSF:    // SZD\r
750               return "MPEG-2.5 LSF";\r
751           }\r
752           return(null);\r
753         }\r
754 \r
755         /**\r
756          * Returns the number of subbands in the current frame.\r
757          * @return number of subbands\r
758          */\r
759         public int number_of_subbands() {return h_number_of_subbands;}\r
760 \r
761         /**\r
762          * Returns Intensity Stereo.\r
763          * (Layer II joint stereo only).\r
764          * Returns the number of subbands which are in stereo mode,\r
765          * subbands above that limit are in intensity stereo mode.\r
766          * @return intensity\r
767          */\r
768         public int intensity_stereo_bound() {return h_intensity_stereo_bound;}\r
769 }\r