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