-public final class Header\r
-{\r
- @LOC("T") public static final int[][] frequencies =\r
- {{22050, 24000, 16000, 1},\r
- {44100, 48000, 32000, 1},\r
- {11025, 12000, 8000, 1}}; // SZD: MPEG25\r
-\r
- /**\r
- * Constant for MPEG-2 LSF version\r
- */\r
- @LOC("T") public static final int MPEG2_LSF = 0;\r
- @LOC("T") public static final int MPEG25_LSF = 2; // SZD\r
-\r
- /**\r
- * Constant for MPEG-1 version\r
- */\r
- @LOC("T") public static final int MPEG1 = 1;\r
-\r
- @LOC("T") public static final int STEREO = 0;\r
- @LOC("T") public static final int JOINT_STEREO = 1;\r
- @LOC("T") public static final int DUAL_CHANNEL = 2;\r
- @LOC("T") public static final int SINGLE_CHANNEL = 3;\r
- @LOC("T") public static final int FOURTYFOUR_POINT_ONE = 0;\r
- @LOC("T") public static final int FOURTYEIGHT=1;\r
- @LOC("T") public static final int THIRTYTWO=2;\r
-\r
- @LOC("H") private int h_layer;\r
- @LOC("H") private int h_protection_bit;\r
- @LOC("H") private int h_bitrate_index;\r
- @LOC("H") private int h_padding_bit;\r
- @LOC("H") private int h_mode_extension;\r
- @LOC("HV") private int h_version;\r
- @LOC("H") private int h_mode;\r
- @LOC("H") private int h_sample_frequency;\r
- @LOC("HNS") private int h_number_of_subbands;\r
- @LOC("HI") private int h_intensity_stereo_bound;\r
- @LOC("H") private boolean h_copyright;\r
- @LOC("H") private boolean h_original;\r
- // VBR support added by E.B\r
- @LOC("T") private double[] h_vbr_time_per_frame = {-1.0, 384.0, 1152.0, 1152.0};\r
- @LOC("T") private boolean h_vbr;\r
- @LOC("T") private int h_vbr_frames;\r
- @LOC("T") private int h_vbr_scale;\r
- @LOC("T") private int h_vbr_bytes;\r
- @LOC("T") private byte[] h_vbr_toc;\r
- \r
- @LOC("SYNC") private byte syncmode = Bitstream.INITIAL_SYNC;\r
- @LOC("C") private Crc16 crc;\r
-\r
- @LOC("C") public short checksum;\r
- @LOC("FS") public int framesize;\r
- @LOC("NS") public int nSlots;\r
-\r
- @LOC("T") private int _headerstring = -1; // E.B\r
-\r
- Header()\r
- {\r
- }\r
- public String toString()\r
- {\r
- StringBuffer buffer = new StringBuffer(200);\r
- buffer.append("Layer ");\r
- buffer.append(layer_string());\r
- buffer.append(" frame ");\r
- buffer.append(mode_string());\r
- buffer.append(' ');\r
- buffer.append(version_string());\r
- if (!checksums())\r
- buffer.append(" no");\r
- buffer.append(" checksums");\r
- buffer.append(' ');\r
- buffer.append(sample_frequency_string());\r
- buffer.append(',');\r
- buffer.append(' ');\r
- buffer.append(bitrate_string());\r
-\r
- String s = buffer.toString();\r
- return s;\r
- }\r
-\r
- /**\r
- * Read a 32-bit header from the bitstream.\r
- */\r
- void read_header(Bitstream stream, Crc16[] crcp) throws BitstreamException\r
- {\r
- int headerstring;\r
- int channel_bitrate;\r
- boolean sync = false;\r
- do\r
- {\r
- headerstring = stream.syncHeader(syncmode);\r
- _headerstring = headerstring; // E.B\r
- if (syncmode == Bitstream.INITIAL_SYNC)\r
- {\r
- h_version = ((headerstring >>> 19) & 1);\r
- if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection\r
- if (h_version == MPEG2_LSF)\r
- h_version = MPEG25_LSF;\r
- else\r
- throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);\r
- if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3)\r
- {\r
- throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);\r
- }\r
- }\r
- h_layer = 4 - (headerstring >>> 17) & 3;\r
- h_protection_bit = (headerstring >>> 16) & 1;\r
- h_bitrate_index = (headerstring >>> 12) & 0xF;\r
- h_padding_bit = (headerstring >>> 9) & 1;\r
- h_mode = ((headerstring >>> 6) & 3);\r
- h_mode_extension = (headerstring >>> 4) & 3;\r
- if (h_mode == JOINT_STEREO)\r
- h_intensity_stereo_bound = (h_mode_extension << 2) + 4;\r
- else\r
- h_intensity_stereo_bound = 0; // should never be used\r
- if (((headerstring >>> 3) & 1) == 1)\r
- h_copyright = true;\r
- if (((headerstring >>> 2) & 1) == 1)\r
- h_original = true;\r
- // calculate number of subbands:\r
- if (h_layer == 1)\r
- h_number_of_subbands = 32;\r
- else\r
- {\r
- channel_bitrate = h_bitrate_index;\r
- // calculate bitrate per channel:\r
- if (h_mode != SINGLE_CHANNEL)\r
- if (channel_bitrate == 4)\r
- channel_bitrate = 1;\r
- else\r
- channel_bitrate -= 4;\r
- if ((channel_bitrate == 1) || (channel_bitrate == 2))\r
- if (h_sample_frequency == THIRTYTWO)\r
- h_number_of_subbands = 12;\r
- else\r
- h_number_of_subbands = 8;\r
- else if ((h_sample_frequency == FOURTYEIGHT) || ((channel_bitrate >= 3) && (channel_bitrate <= 5)))\r
- h_number_of_subbands = 27;\r
- else\r
- h_number_of_subbands = 30;\r
- }\r
- if (h_intensity_stereo_bound > h_number_of_subbands)\r
- h_intensity_stereo_bound = h_number_of_subbands;\r
- // calculate framesize and nSlots\r
- calculate_framesize();\r
- // read framedata:\r
- int framesizeloaded = stream.read_frame_data(framesize);\r
- if ((framesize >=0) && (framesizeloaded != framesize))\r
- {\r
- // Data loaded does not match to expected framesize,\r
- // it might be an ID3v1 TAG. (Fix 11/17/04).\r
- throw stream.newBitstreamException(Bitstream.INVALIDFRAME);\r
- }\r
- if (stream.isSyncCurrentPosition(syncmode))\r
- {\r
- if (syncmode == Bitstream.INITIAL_SYNC)\r
- {\r
- syncmode = Bitstream.STRICT_SYNC;\r
- stream.set_syncword(headerstring & 0xFFF80CC0);\r
- }\r
- sync = true;\r
- }\r
- else\r
- {\r
- stream.unreadFrame();\r
- }\r
- }\r
- while (!sync);\r
- stream.parse_frame();\r
- if (h_protection_bit == 0)\r
- {\r
- // frame contains a crc checksum\r
- checksum = (short) stream.get_bits(16);\r
- if (crc == null)\r
- crc = new Crc16();\r
- crc.add_bits(headerstring, 16);\r
- crcp[0] = crc;\r
- }\r
- else\r
- crcp[0] = null;\r
- if (h_sample_frequency == FOURTYFOUR_POINT_ONE)\r
- {\r
- /*\r
- if (offset == null)\r
- {\r
- int max = max_number_of_frames(stream);\r
- offset = new int[max];\r
- for(int i=0; i<max; i++) offset[i] = 0;\r
- }\r
- // E.B : Investigate more\r
- int cf = stream.current_frame();\r
- int lf = stream.last_frame();\r
- if ((cf > 0) && (cf == lf))\r
- {\r
- offset[cf] = offset[cf-1] + h_padding_bit;\r
- }\r
- else\r
- {\r
- offset[0] = h_padding_bit;\r
- }\r
- */\r
- }\r
- }\r
-\r
- /**\r
- * Parse frame to extract optionnal VBR frame.\r
- * @param firstframe\r
- * @author E.B (javalayer@javazoom.net)\r
- */\r
- void parseVBR(byte[] firstframe) throws BitstreamException\r
- {\r
- // Trying Xing header.\r
- String xing = "Xing";\r
- byte tmp[] = new byte[4];\r
- int offset = 0;\r
- // Compute "Xing" offset depending on MPEG version and channels.\r
- if (h_version == MPEG1) \r
- {\r
- if (h_mode == SINGLE_CHANNEL) offset=21-4;\r
- else offset=36-4;\r
- } \r
- else \r
- {\r
- if (h_mode == SINGLE_CHANNEL) offset=13-4;\r
- else offset = 21-4; \r
- }\r
- try\r
- {\r
- System.arraycopy(firstframe, offset, tmp, 0, 4);\r
- // Is "Xing" ?\r
- if (xing.equals(new String(tmp)))\r
- {\r
- //Yes.\r
- h_vbr = true;\r
- h_vbr_frames = -1;\r
- h_vbr_bytes = -1;\r
- h_vbr_scale = -1;\r
- h_vbr_toc = new byte[100];\r
- \r
- int length = 4;\r
- // Read flags.\r
- byte flags[] = new byte[4];\r
- System.arraycopy(firstframe, offset + length, flags, 0, flags.length);\r
- length += flags.length;\r
- // Read number of frames (if available).\r
- if ((flags[3] & (byte) (1 << 0)) != 0)\r
- {\r
- System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
- h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;\r
- length += 4; \r
- }\r
- // Read size (if available).\r
- if ((flags[3] & (byte) (1 << 1)) != 0)\r
- {\r
- System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
- h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;\r
- length += 4; \r
- }\r
- // Read TOC (if available).\r
- if ((flags[3] & (byte) (1 << 2)) != 0)\r
- {\r
- System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length);\r
- length += h_vbr_toc.length; \r
- }\r
- // Read scale (if available).\r
- if ((flags[3] & (byte) (1 << 3)) != 0)\r
- {\r
- System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
- h_vbr_scale = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;\r
- length += 4; \r
- }\r
- //System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes); \r
- } \r
- }\r
- catch (ArrayIndexOutOfBoundsException e)\r
- {\r
- throw new BitstreamException("XingVBRHeader Corrupted",e);\r
- }\r
- \r
- // Trying VBRI header. \r
- String vbri = "VBRI";\r
- offset = 36-4;\r
- try\r
- {\r
- System.arraycopy(firstframe, offset, tmp, 0, 4);\r
- // Is "VBRI" ?\r
- if (vbri.equals(new String(tmp)))\r
- {\r
- //Yes.\r
- h_vbr = true;\r
- h_vbr_frames = -1;\r
- h_vbr_bytes = -1;\r
- h_vbr_scale = -1;\r
- h_vbr_toc = new byte[100];\r
- // Bytes. \r
- int length = 4 + 6;\r
- System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
- h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;\r
- length += 4; \r
- // Frames. \r
- System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
- h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;\r
- length += 4; \r
- //System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes);\r
- // TOC\r
- // TODO \r
- }\r
- }\r
- catch (ArrayIndexOutOfBoundsException e)\r
- {\r
- throw new BitstreamException("VBRIVBRHeader Corrupted",e);\r
- }\r
- }\r
- \r
- // Functions to query header contents:\r
- /**\r
- * Returns version.\r
- */\r
- @RETURNLOC("OUT")\r
- public int version() { return h_version; }\r
-\r
- /**\r
- * Returns Layer ID.\r
- */\r
- @RETURNLOC("OUT")\r
- public int layer() { return h_layer; }\r
-\r
- /**\r
- * Returns bitrate index.\r
- */\r
- @RETURNLOC("OUT")\r
- public int bitrate_index() { return h_bitrate_index; }\r
-\r
- /**\r
- * Returns Sample Frequency.\r
- */\r
- public int sample_frequency() { return h_sample_frequency; }\r
-\r
- /**\r
- * Returns Frequency.\r
- */\r
- public int frequency() {return frequencies[h_version][h_sample_frequency];}\r
-\r
- /**\r
- * Returns Mode.\r
- */\r
- @RETURNLOC("OUT")\r
- public int mode() { return h_mode; }\r
-\r
- /**\r
- * Returns Protection bit.\r
- */\r
- public boolean checksums()\r
- {\r
- if (h_protection_bit == 0) return true;\r
- else return false;\r
- }\r
-\r
- /**\r
- * Returns Copyright.\r
- */\r
- public boolean copyright() { return h_copyright; }\r
-\r
- /**\r
- * Returns Original.\r
- */\r
- public boolean original() { return h_original; }\r
-\r
- /**\r
- * Return VBR.\r
- * @return true if VBR header is found\r
- */\r
- public boolean vbr() { return h_vbr; }\r
-\r
- /**\r
- * Return VBR scale.\r
- * @return scale of -1 if not available\r
- */\r
- public int vbr_scale() { return h_vbr_scale; }\r
-\r
- /**\r
- * Return VBR TOC.\r
- * @return vbr toc ot null if not available\r
- */\r
- public byte[] vbr_toc() { return h_vbr_toc; }\r
-\r
- /**\r
- * Returns Checksum flag.\r
- * Compares computed checksum with stream checksum.\r
- */\r
- @RETURNLOC("OUT")\r
- public boolean checksum_ok () { return (checksum == crc.checksum()); }\r
-\r
- // Seeking and layer III stuff\r
- /**\r
- * Returns Layer III Padding bit.\r
- */\r
- public boolean padding()\r
- {\r
- if (h_padding_bit == 0) return false;\r
- else return true;\r
- }\r
-\r
- /**\r
- * Returns Slots.\r
- */\r
- @RETURNLOC("OUT")\r
- public int slots() { return nSlots; }\r
-\r
- /**\r
- * Returns Mode Extension.\r
- */\r
- @RETURNLOC("OUT")\r
- public int mode_extension() { return h_mode_extension; }\r
-\r
- // E.B -> private to public\r
- @LOC("T") public static final int bitrates[][][] = {\r
- {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,\r
- 112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0},\r
- {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
- 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},\r
- {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
- 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}},\r
-\r
- {{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000,\r
- 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0},\r
- {0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,\r
- 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0},\r
- {0 /*free format*/, 32000, 40000, 48000, 56000, 64000, 80000,\r
- 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}},\r
- // SZD: MPEG2.5\r
- {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,\r
- 112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0},\r
- {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
- 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},\r
- {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,\r
- 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}},\r
-\r
- };\r
-\r
- // E.B -> private to public\r
- /**\r
- * Calculate Frame size.\r
- * Calculates framesize in bytes excluding header size.\r
- */\r
- public int calculate_framesize()\r
- {\r
-\r
- if (h_layer == 1)\r
- {\r
- framesize = (12 * bitrates[h_version][0][h_bitrate_index]) /\r
- frequencies[h_version][h_sample_frequency];\r
- if (h_padding_bit != 0 ) framesize++;\r
- framesize <<= 2; // one slot is 4 bytes long\r
- nSlots = 0;\r
- }\r
- else\r
- {\r
- framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) /\r
- frequencies[h_version][h_sample_frequency];\r
- if (h_version == MPEG2_LSF || h_version == MPEG25_LSF) framesize >>= 1; // SZD\r
- if (h_padding_bit != 0) framesize++;\r
- // Layer III slots\r
- if (h_layer == 3)\r
- {\r
- if (h_version == MPEG1)\r
- {\r
- nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side info size\r
- - ((h_protection_bit!=0) ? 0 : 2) // CRC size\r
- - 4; // header size\r
- }\r
- else\r
- { // MPEG-2 LSF, SZD: MPEG-2.5 LSF\r
- nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side info size\r
- - ((h_protection_bit!=0) ? 0 : 2) // CRC size\r
- - 4; // header size\r
- }\r
- }\r
- else\r
- {\r
- nSlots = 0;\r
- }\r
- }\r
- framesize -= 4; // subtract header size\r
- return framesize;\r
- }\r
-\r
- /**\r
- * Returns the maximum number of frames in the stream.\r
- * @param streamsize\r
- * @return number of frames\r
- */\r
- public int max_number_of_frames(int streamsize) // E.B\r
- {\r
- if (h_vbr == true) return h_vbr_frames;\r
- else\r
- {\r
- if ((framesize + 4 - h_padding_bit) == 0) return 0;\r
- else return(streamsize / (framesize + 4 - h_padding_bit));\r
- }\r
- }\r
-\r
- /**\r
- * Returns the maximum number of frames in the stream.\r
- * @param streamsize\r
- * @return number of frames\r
- */\r
- public int min_number_of_frames(int streamsize) // E.B\r
- {\r
- if (h_vbr == true) return h_vbr_frames;\r
- else\r
- {\r
- if ((framesize + 5 - h_padding_bit) == 0) return 0;\r
- else return(streamsize / (framesize + 5 - h_padding_bit));\r
- }\r
- }\r
-\r
-\r
- /**\r
- * Returns ms/frame.\r
- * @return milliseconds per frame\r
- */\r
- public float ms_per_frame() // E.B\r
- {\r
- if (h_vbr == true)\r
- { \r
- double tpf = h_vbr_time_per_frame[layer()] / frequency();\r
- if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF)) tpf /= 2;\r
- return ((float) (tpf * 1000));\r
- }\r
- else\r
- {\r
- float ms_per_frame_array[][] = {{8.707483f, 8.0f, 12.0f},\r
- {26.12245f, 24.0f, 36.0f},\r
- {26.12245f, 24.0f, 36.0f}};\r
- return(ms_per_frame_array[h_layer-1][h_sample_frequency]);\r
- }\r
- }\r
-\r
- /**\r
- * Returns total ms.\r
- * @param streamsize\r
- * @return total milliseconds\r
- */\r
- public float total_ms(int streamsize) // E.B\r
- {\r
- return(max_number_of_frames(streamsize) * ms_per_frame());\r
- }\r
-\r
- /**\r
- * Returns synchronized header.\r
- */\r
- public int getSyncHeader() // E.B\r
- {\r
- return _headerstring;\r
- }\r
-\r
- // functions which return header informations as strings:\r
- /**\r
- * Return Layer version.\r
- */\r
- public String layer_string()\r
- {\r
- switch (h_layer)\r
- {\r
- case 1:\r
- return "I";\r
- case 2:\r
- return "II";\r
- case 3:\r
- return "III";\r
- }\r
- return null;\r
- }\r
-\r
- // E.B -> private to public\r
- @LOC("T") public static final String bitrate_str[][][] = {\r
- {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
- "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s",\r
- "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s",\r
- "forbidden"},\r
- {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
- "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
- "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
- "forbidden"},\r
- {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
- "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
- "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
- "forbidden"}},\r
-\r
- {{"free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s",\r
- "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s",\r
- "320 kbit/s", "352 kbit/s", "384 kbit/s", "416 kbit/s", "448 kbit/s",\r
- "forbidden"},\r
- {"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
- "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s",\r
- "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "384 kbit/s",\r
- "forbidden"},\r
- {"free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s",\r
- "64 kbit/s", "80 kbit/s" , "96 kbit/s", "112 kbit/s", "128 kbit/s",\r
- "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s",\r
- "forbidden"}},\r
- // SZD: MPEG2.5\r
- {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
- "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s",\r
- "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s",\r
- "forbidden"},\r
- {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
- "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
- "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
- "forbidden"},\r
- {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",\r
- "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
- "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",\r
- "forbidden"}},\r
- };\r
-\r
- /**\r
- * Return Bitrate.\r
- * @return bitrate in bps\r
- */\r
- public String bitrate_string()\r
- {\r
- if (h_vbr == true)\r
- {\r
- return Integer.toString(bitrate()/1000)+" kb/s"; \r
- }\r
- else return bitrate_str[h_version][h_layer - 1][h_bitrate_index];\r
- }\r
-\r
- /**\r
- * Return Bitrate.\r
- * @return bitrate in bps and average bitrate for VBR header\r
- */\r
- public int bitrate()\r
- {\r
- if (h_vbr == true)\r
- {\r
- return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames)))*1000; \r
- }\r
- else return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
- }\r
-\r
- /**\r
- * Return Instant Bitrate.\r
- * Bitrate for VBR is not constant.\r
- * @return bitrate in bps\r
- */\r
- public int bitrate_instant()\r
- {\r
- return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
- }\r
-\r
- /**\r
- * Returns Frequency\r
- * @return frequency string in kHz\r
- */\r
- public String sample_frequency_string()\r
- {\r
- switch (h_sample_frequency)\r
- {\r
- case THIRTYTWO:\r
- if (h_version == MPEG1)\r
- return "32 kHz";\r
- else if (h_version == MPEG2_LSF)\r
- return "16 kHz";\r
- else // SZD\r
- return "8 kHz";\r
- case FOURTYFOUR_POINT_ONE:\r
- if (h_version == MPEG1)\r
- return "44.1 kHz";\r
- else if (h_version == MPEG2_LSF)\r
- return "22.05 kHz";\r
- else // SZD\r
- return "11.025 kHz";\r
- case FOURTYEIGHT:\r
- if (h_version == MPEG1)\r
- return "48 kHz";\r
- else if (h_version == MPEG2_LSF)\r
- return "24 kHz";\r
- else // SZD\r
- return "12 kHz";\r
- }\r
- return(null);\r
- }\r
-\r
- /**\r
- * Returns Mode.\r
- */\r
- public String mode_string()\r
- {\r
- switch (h_mode)\r
- {\r
- case STEREO:\r
- return "Stereo";\r
- case JOINT_STEREO:\r
- return "Joint stereo";\r
- case DUAL_CHANNEL:\r
- return "Dual channel";\r
- case SINGLE_CHANNEL:\r
- return "Single channel";\r
- }\r
- return null;\r
- }\r
-\r
- /**\r
- * Returns Version.\r
- * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF\r
- */\r
- public String version_string()\r
- {\r
- switch (h_version)\r
- {\r
- case MPEG1:\r
- return "MPEG-1";\r
- case MPEG2_LSF:\r
- return "MPEG-2 LSF";\r
- case MPEG25_LSF: // SZD\r
- return "MPEG-2.5 LSF";\r
- }\r
- return(null);\r
- }\r
-\r
- /**\r
- * Returns the number of subbands in the current frame.\r
- * @return number of subbands\r
- */\r
- @RETURNLOC("OUT")\r
- public int number_of_subbands() {return h_number_of_subbands;}\r
-\r
- /**\r
- * Returns Intensity Stereo.\r
- * (Layer II joint stereo only).\r
- * Returns the number of subbands which are in stereo mode,\r
- * subbands above that limit are in intensity stereo mode.\r
- * @return intensity\r
- */\r
- @RETURNLOC("OUT")\r
- public int intensity_stereo_bound() {return h_intensity_stereo_bound;}\r
+public final class Header {\r
+\r
+ public static final int[][] frequencies = { { 22050, 24000, 16000, 1 },\r
+ { 44100, 48000, 32000, 1 }, { 11025, 12000, 8000, 1 } }; // SZD: MPEG25\r
+\r
+ /**\r
+ * Constant for MPEG-2 LSF version\r
+ */\r
+ public static final int MPEG2_LSF = 0;\r
+ public static final int MPEG25_LSF = 2; // SZD\r
+\r
+ /**\r
+ * Constant for MPEG-1 version\r
+ */\r
+ public static final int MPEG1 = 1;\r
+\r
+ public static final int STEREO = 0;\r
+ public static final int JOINT_STEREO = 1;\r
+ public static final int DUAL_CHANNEL = 2;\r
+ public static final int SINGLE_CHANNEL = 3;\r
+ public static final int FOURTYFOUR_POINT_ONE = 0;\r
+ public static final int FOURTYEIGHT = 1;\r
+ public static final int THIRTYTWO = 2;\r
+\r
+ @LOC("H")\r
+ private int h_layer;\r
+ @LOC("H")\r
+ private int h_protection_bit;\r
+ @LOC("H")\r
+ private int h_bitrate_index;\r
+ @LOC("H")\r
+ private int h_padding_bit;\r
+ @LOC("H")\r
+ private int h_mode_extension;\r
+ @LOC("HV")\r
+ private int h_version;\r
+ @LOC("H")\r
+ private int h_mode;\r
+ @LOC("H")\r
+ private int h_sample_frequency;\r
+ @LOC("HNS")\r
+ private int h_number_of_subbands;\r
+ @LOC("HI")\r
+ private int h_intensity_stereo_bound;\r
+ @LOC("H")\r
+ private boolean h_copyright;\r
+ @LOC("H")\r
+ private boolean h_original;\r
+ // VBR support added by E.B\r
+ @LOC("T")\r
+ private double[] h_vbr_time_per_frame = { -1.0, 384.0, 1152.0, 1152.0 };\r
+ @LOC("T")\r
+ private boolean h_vbr;\r
+ @LOC("T")\r
+ private int h_vbr_frames;\r
+ @LOC("T")\r
+ private int h_vbr_scale;\r
+ @LOC("T")\r
+ private int h_vbr_bytes;\r
+ @LOC("T")\r
+ private byte[] h_vbr_toc;\r
+\r
+ @LOC("SYNC")\r
+ private byte syncmode = Bitstream.INITIAL_SYNC;\r
+ @LOC("C")\r
+ private Crc16 crc;\r
+\r
+ @LOC("C")\r
+ public short checksum;\r
+ @LOC("FS")\r
+ public int framesize;\r
+ @LOC("NS")\r
+ public int nSlots;\r
+\r
+ @LOC("T")\r
+ private int _headerstring = -1; // E.B\r
+\r
+ Header() {\r
+ }\r
+\r
+ public String toString() {\r
+ StringBuffer buffer = new StringBuffer(200);\r
+ buffer.append("Layer ");\r
+ buffer.append(layer_string());\r
+ buffer.append(" frame ");\r
+ buffer.append(mode_string());\r
+ buffer.append(' ');\r
+ buffer.append(version_string());\r
+ if (!checksums())\r
+ buffer.append(" no");\r
+ buffer.append(" checksums");\r
+ buffer.append(' ');\r
+ buffer.append(sample_frequency_string());\r
+ buffer.append(',');\r
+ buffer.append(' ');\r
+ buffer.append(bitrate_string());\r
+\r
+ String s = buffer.toString();\r
+ return s;\r
+ }\r
+\r
+ /**\r
+ * Read a 32-bit header from the bitstream.\r
+ */\r
+ void read_header(Bitstream stream, Crc16[] crcp) throws BitstreamException {\r
+ int headerstring;\r
+ int channel_bitrate;\r
+ boolean sync = false;\r
+ do {\r
+ headerstring = stream.syncHeader(syncmode);\r
+ _headerstring = headerstring; // E.B\r
+ if (syncmode == Bitstream.INITIAL_SYNC) {\r
+ h_version = ((headerstring >>> 19) & 1);\r
+ if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection\r
+ if (h_version == MPEG2_LSF)\r
+ h_version = MPEG25_LSF;\r
+ else\r
+ throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);\r
+ if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3) {\r
+ throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);\r
+ }\r
+ }\r
+ h_layer = 4 - (headerstring >>> 17) & 3;\r
+ h_protection_bit = (headerstring >>> 16) & 1;\r
+ h_bitrate_index = (headerstring >>> 12) & 0xF;\r
+ h_padding_bit = (headerstring >>> 9) & 1;\r
+ h_mode = ((headerstring >>> 6) & 3);\r
+ h_mode_extension = (headerstring >>> 4) & 3;\r
+ if (h_mode == JOINT_STEREO)\r
+ h_intensity_stereo_bound = (h_mode_extension << 2) + 4;\r
+ else\r
+ h_intensity_stereo_bound = 0; // should never be used\r
+ if (((headerstring >>> 3) & 1) == 1)\r
+ h_copyright = true;\r
+ if (((headerstring >>> 2) & 1) == 1)\r
+ h_original = true;\r
+ // calculate number of subbands:\r
+ if (h_layer == 1)\r
+ h_number_of_subbands = 32;\r
+ else {\r
+ channel_bitrate = h_bitrate_index;\r
+ // calculate bitrate per channel:\r
+ if (h_mode != SINGLE_CHANNEL)\r
+ if (channel_bitrate == 4)\r
+ channel_bitrate = 1;\r
+ else\r
+ channel_bitrate -= 4;\r
+ if ((channel_bitrate == 1) || (channel_bitrate == 2))\r
+ if (h_sample_frequency == THIRTYTWO)\r
+ h_number_of_subbands = 12;\r
+ else\r
+ h_number_of_subbands = 8;\r
+ else if ((h_sample_frequency == FOURTYEIGHT)\r
+ || ((channel_bitrate >= 3) && (channel_bitrate <= 5)))\r
+ h_number_of_subbands = 27;\r
+ else\r
+ h_number_of_subbands = 30;\r
+ }\r
+ if (h_intensity_stereo_bound > h_number_of_subbands)\r
+ h_intensity_stereo_bound = h_number_of_subbands;\r
+ // calculate framesize and nSlots\r
+ calculate_framesize();\r
+ // read framedata:\r
+ int framesizeloaded = stream.read_frame_data(framesize);\r
+ if ((framesize >= 0) && (framesizeloaded != framesize)) {\r
+ // Data loaded does not match to expected framesize,\r
+ // it might be an ID3v1 TAG. (Fix 11/17/04).\r
+ throw stream.newBitstreamException(Bitstream.INVALIDFRAME);\r
+ }\r
+ if (stream.isSyncCurrentPosition(syncmode)) {\r
+ if (syncmode == Bitstream.INITIAL_SYNC) {\r
+ syncmode = Bitstream.STRICT_SYNC;\r
+ stream.set_syncword(headerstring & 0xFFF80CC0);\r
+ }\r
+ sync = true;\r
+ } else {\r
+ stream.unreadFrame();\r
+ }\r
+ } while (!sync);\r
+ stream.parse_frame();\r
+ if (h_protection_bit == 0) {\r
+ // frame contains a crc checksum\r
+ checksum = (short) stream.get_bits(16);\r
+ if (crc == null)\r
+ crc = new Crc16();\r
+ crc.add_bits(headerstring, 16);\r
+ crcp[0] = crc;\r
+ } else\r
+ crcp[0] = null;\r
+ if (h_sample_frequency == FOURTYFOUR_POINT_ONE) {\r
+ /*\r
+ * if (offset == null) { int max = max_number_of_frames(stream); offset =\r
+ * new int[max]; for(int i=0; i<max; i++) offset[i] = 0; } // E.B :\r
+ * Investigate more int cf = stream.current_frame(); int lf =\r
+ * stream.last_frame(); if ((cf > 0) && (cf == lf)) { offset[cf] =\r
+ * offset[cf-1] + h_padding_bit; } else { offset[0] = h_padding_bit; }\r
+ */\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Parse frame to extract optionnal VBR frame.\r
+ * \r
+ * @param firstframe\r
+ * @author E.B (javalayer@javazoom.net)\r
+ */\r
+ void parseVBR(byte[] firstframe) throws BitstreamException {\r
+ // Trying Xing header.\r
+ String xing = "Xing";\r
+ byte tmp[] = new byte[4];\r
+ int offset = 0;\r
+ // Compute "Xing" offset depending on MPEG version and channels.\r
+ if (h_version == MPEG1) {\r
+ if (h_mode == SINGLE_CHANNEL)\r
+ offset = 21 - 4;\r
+ else\r
+ offset = 36 - 4;\r
+ } else {\r
+ if (h_mode == SINGLE_CHANNEL)\r
+ offset = 13 - 4;\r
+ else\r
+ offset = 21 - 4;\r
+ }\r
+ try {\r
+ System.arraycopy(firstframe, offset, tmp, 0, 4);\r
+ // Is "Xing" ?\r
+ if (xing.equals(new String(tmp))) {\r
+ // Yes.\r
+ h_vbr = true;\r
+ h_vbr_frames = -1;\r
+ h_vbr_bytes = -1;\r
+ h_vbr_scale = -1;\r
+ h_vbr_toc = new byte[100];\r
+\r
+ int length = 4;\r
+ // Read flags.\r
+ byte flags[] = new byte[4];\r
+ System.arraycopy(firstframe, offset + length, flags, 0, flags.length);\r
+ length += flags.length;\r
+ // Read number of frames (if available).\r
+ if ((flags[3] & (byte) (1 << 0)) != 0) {\r
+ System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
+ h_vbr_frames =\r
+ (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)\r
+ & 0x0000FF00 | tmp[3] & 0x000000FF;\r
+ length += 4;\r
+ }\r
+ // Read size (if available).\r
+ if ((flags[3] & (byte) (1 << 1)) != 0) {\r
+ System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
+ h_vbr_bytes =\r
+ (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)\r
+ & 0x0000FF00 | tmp[3] & 0x000000FF;\r
+ length += 4;\r
+ }\r
+ // Read TOC (if available).\r
+ if ((flags[3] & (byte) (1 << 2)) != 0) {\r
+ System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length);\r
+ length += h_vbr_toc.length;\r
+ }\r
+ // Read scale (if available).\r
+ if ((flags[3] & (byte) (1 << 3)) != 0) {\r
+ System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
+ h_vbr_scale =\r
+ (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8)\r
+ & 0x0000FF00 | tmp[3] & 0x000000FF;\r
+ length += 4;\r
+ }\r
+ // System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames\r
+ // +" Size:"+h_vbr_bytes);\r
+ }\r
+ } catch (ArrayIndexOutOfBoundsException e) {\r
+ throw new BitstreamException("XingVBRHeader Corrupted", e);\r
+ }\r
+\r
+ // Trying VBRI header.\r
+ String vbri = "VBRI";\r
+ offset = 36 - 4;\r
+ try {\r
+ System.arraycopy(firstframe, offset, tmp, 0, 4);\r
+ // Is "VBRI" ?\r
+ if (vbri.equals(new String(tmp))) {\r
+ // Yes.\r
+ h_vbr = true;\r
+ h_vbr_frames = -1;\r
+ h_vbr_bytes = -1;\r
+ h_vbr_scale = -1;\r
+ h_vbr_toc = new byte[100];\r
+ // Bytes.\r
+ int length = 4 + 6;\r
+ System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
+ h_vbr_bytes =\r
+ (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00\r
+ | tmp[3] & 0x000000FF;\r
+ length += 4;\r
+ // Frames.\r
+ System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);\r
+ h_vbr_frames =\r
+ (tmp[0] << 24) & 0xFF000000 | (tmp[1] << 16) & 0x00FF0000 | (tmp[2] << 8) & 0x0000FF00\r
+ | tmp[3] & 0x000000FF;\r
+ length += 4;\r
+ // System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames\r
+ // +" Size:"+h_vbr_bytes);\r
+ // TOC\r
+ // TODO\r
+ }\r
+ } catch (ArrayIndexOutOfBoundsException e) {\r
+ throw new BitstreamException("VBRIVBRHeader Corrupted", e);\r
+ }\r
+ }\r
+\r
+ // Functions to query header contents:\r
+ /**\r
+ * Returns version.\r
+ */\r
+ @RETURNLOC("OUT")\r
+ public int version() {\r
+ return h_version;\r
+ }\r
+\r
+ /**\r
+ * Returns Layer ID.\r
+ */\r
+ @RETURNLOC("OUT")\r
+ public int layer() {\r
+ return h_layer;\r
+ }\r
+\r
+ /**\r
+ * Returns bitrate index.\r
+ */\r
+ @RETURNLOC("OUT")\r
+ public int bitrate_index() {\r
+ return h_bitrate_index;\r
+ }\r
+\r
+ /**\r
+ * Returns Sample Frequency.\r
+ */\r
+ public int sample_frequency() {\r
+ return h_sample_frequency;\r
+ }\r
+\r
+ /**\r
+ * Returns Frequency.\r
+ */\r
+ public int frequency() {\r
+ return frequencies[h_version][h_sample_frequency];\r
+ }\r
+\r
+ /**\r
+ * Returns Mode.\r
+ */\r
+ @RETURNLOC("OUT")\r
+ public int mode() {\r
+ return h_mode;\r
+ }\r
+\r
+ /**\r
+ * Returns Protection bit.\r
+ */\r
+ public boolean checksums() {\r
+ if (h_protection_bit == 0)\r
+ return true;\r
+ else\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Returns Copyright.\r
+ */\r
+ public boolean copyright() {\r
+ return h_copyright;\r
+ }\r
+\r
+ /**\r
+ * Returns Original.\r
+ */\r
+ public boolean original() {\r
+ return h_original;\r
+ }\r
+\r
+ /**\r
+ * Return VBR.\r
+ * \r
+ * @return true if VBR header is found\r
+ */\r
+ public boolean vbr() {\r
+ return h_vbr;\r
+ }\r
+\r
+ /**\r
+ * Return VBR scale.\r
+ * \r
+ * @return scale of -1 if not available\r
+ */\r
+ public int vbr_scale() {\r
+ return h_vbr_scale;\r
+ }\r
+\r
+ /**\r
+ * Return VBR TOC.\r
+ * \r
+ * @return vbr toc ot null if not available\r
+ */\r
+ public byte[] vbr_toc() {\r
+ return h_vbr_toc;\r
+ }\r
+\r
+ /**\r
+ * Returns Checksum flag. Compares computed checksum with stream checksum.\r
+ */\r
+ @RETURNLOC("OUT")\r
+ public boolean checksum_ok() {\r
+ return (checksum == crc.checksum());\r
+ }\r
+\r
+ // Seeking and layer III stuff\r
+ /**\r
+ * Returns Layer III Padding bit.\r
+ */\r
+ public boolean padding() {\r
+ if (h_padding_bit == 0)\r
+ return false;\r
+ else\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Returns Slots.\r
+ */\r
+ @RETURNLOC("OUT")\r
+ public int slots() {\r
+ return nSlots;\r
+ }\r
+\r
+ /**\r
+ * Returns Mode Extension.\r
+ */\r
+ @RETURNLOC("OUT")\r
+ public int mode_extension() {\r
+ return h_mode_extension;\r
+ }\r
+\r
+ // E.B -> private to public\r
+ @LOC("T")\r
+ public static final int bitrates[][][] = {\r
+ {\r
+ { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,\r
+ 160000, 176000, 192000, 224000, 256000, 0 },\r
+ { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
+ 96000, 112000, 128000, 144000, 160000, 0 },\r
+ { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
+ 96000, 112000, 128000, 144000, 160000, 0 } },\r
+\r
+ {\r
+ { 0 /* free format */, 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000,\r
+ 288000, 320000, 352000, 384000, 416000, 448000, 0 },\r
+ { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000,\r
+ 192000, 224000, 256000, 320000, 384000, 0 },\r
+ { 0 /* free format */, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000,\r
+ 160000, 192000, 224000, 256000, 320000, 0 } },\r
+ // SZD: MPEG2.5\r
+ {\r
+ { 0 /* free format */, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,\r
+ 160000, 176000, 192000, 224000, 256000, 0 },\r
+ { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
+ 96000, 112000, 128000, 144000, 160000, 0 },\r
+ { 0 /* free format */, 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000,\r
+ 96000, 112000, 128000, 144000, 160000, 0 } },\r
+\r
+ };\r
+\r
+ // E.B -> private to public\r
+ /**\r
+ * Calculate Frame size. Calculates framesize in bytes excluding header size.\r
+ */\r
+ public int calculate_framesize() {\r
+\r
+ if (h_layer == 1) {\r
+ framesize =\r
+ (12 * bitrates[h_version][0][h_bitrate_index])\r
+ / frequencies[h_version][h_sample_frequency];\r
+ if (h_padding_bit != 0)\r
+ framesize++;\r
+ framesize <<= 2; // one slot is 4 bytes long\r
+ nSlots = 0;\r
+ } else {\r
+ framesize =\r
+ (144 * bitrates[h_version][h_layer - 1][h_bitrate_index])\r
+ / frequencies[h_version][h_sample_frequency];\r
+ if (h_version == MPEG2_LSF || h_version == MPEG25_LSF)\r
+ framesize >>= 1; // SZD\r
+ if (h_padding_bit != 0)\r
+ framesize++;\r
+ // Layer III slots\r
+ if (h_layer == 3) {\r
+ if (h_version == MPEG1) {\r
+ nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side\r
+ // info\r
+ // size\r
+ - ((h_protection_bit != 0) ? 0 : 2) // CRC size\r
+ - 4; // header size\r
+ } else { // MPEG-2 LSF, SZD: MPEG-2.5 LSF\r
+ nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side\r
+ // info\r
+ // size\r
+ - ((h_protection_bit != 0) ? 0 : 2) // CRC size\r
+ - 4; // header size\r
+ }\r
+ } else {\r
+ nSlots = 0;\r
+ }\r
+ }\r
+ framesize -= 4; // subtract header size\r
+ return framesize;\r
+ }\r
+\r
+ /**\r
+ * Returns the maximum number of frames in the stream.\r
+ * \r
+ * @param streamsize\r
+ * @return number of frames\r
+ */\r
+ public int max_number_of_frames(int streamsize) // E.B\r
+ {\r
+ if (h_vbr == true)\r
+ return h_vbr_frames;\r
+ else {\r
+ if ((framesize + 4 - h_padding_bit) == 0)\r
+ return 0;\r
+ else\r
+ return (streamsize / (framesize + 4 - h_padding_bit));\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Returns the maximum number of frames in the stream.\r
+ * \r
+ * @param streamsize\r
+ * @return number of frames\r
+ */\r
+ public int min_number_of_frames(int streamsize) // E.B\r
+ {\r
+ if (h_vbr == true)\r
+ return h_vbr_frames;\r
+ else {\r
+ if ((framesize + 5 - h_padding_bit) == 0)\r
+ return 0;\r
+ else\r
+ return (streamsize / (framesize + 5 - h_padding_bit));\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Returns ms/frame.\r
+ * \r
+ * @return milliseconds per frame\r
+ */\r
+ public float ms_per_frame() // E.B\r
+ {\r
+ if (h_vbr == true) {\r
+ double tpf = h_vbr_time_per_frame[layer()] / frequency();\r
+ if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF))\r
+ tpf /= 2;\r
+ return ((float) (tpf * 1000));\r
+ } else {\r
+ float ms_per_frame_array[][] =\r
+ { { 8.707483f, 8.0f, 12.0f }, { 26.12245f, 24.0f, 36.0f }, { 26.12245f, 24.0f, 36.0f } };\r
+ return (ms_per_frame_array[h_layer - 1][h_sample_frequency]);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Returns total ms.\r
+ * \r
+ * @param streamsize\r
+ * @return total milliseconds\r
+ */\r
+ public float total_ms(int streamsize) // E.B\r
+ {\r
+ return (max_number_of_frames(streamsize) * ms_per_frame());\r
+ }\r
+\r
+ /**\r
+ * Returns synchronized header.\r
+ */\r
+ public int getSyncHeader() // E.B\r
+ {\r
+ return _headerstring;\r
+ }\r
+\r
+ // functions which return header informations as strings:\r
+ /**\r
+ * Return Layer version.\r
+ */\r
+ public String layer_string() {\r
+ switch (h_layer) {\r
+ case 1:\r
+ return "I";\r
+ case 2:\r
+ return "II";\r
+ case 3:\r
+ return "III";\r
+ }\r
+ return null;\r
+ }\r
+\r
+ // E.B -> private to public\r
+ @LOC("T")\r
+ public static final String bitrate_str[][][] = {\r
+ {\r
+ { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
+ "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s",\r
+ "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" },\r
+ { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
+ "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
+ "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" },\r
+ { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
+ "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
+ "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } },\r
+\r
+ {\r
+ { "free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", "160 kbit/s",\r
+ "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", "320 kbit/s", "352 kbit/s",\r
+ "384 kbit/s", "416 kbit/s", "448 kbit/s", "forbidden" },\r
+ { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
+ "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s", "224 kbit/s",\r
+ "256 kbit/s", "320 kbit/s", "384 kbit/s", "forbidden" },\r
+ { "free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",\r
+ "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s",\r
+ "224 kbit/s", "256 kbit/s", "320 kbit/s", "forbidden" } },\r
+ // SZD: MPEG2.5\r
+ {\r
+ { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",\r
+ "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s",\r
+ "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" },\r
+ { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
+ "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
+ "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" },\r
+ { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s",\r
+ "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s",\r
+ "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } }, };\r
+\r
+ /**\r
+ * Return Bitrate.\r
+ * \r
+ * @return bitrate in bps\r
+ */\r
+ public String bitrate_string() {\r
+ if (h_vbr == true) {\r
+ return Integer.toString(bitrate() / 1000) + " kb/s";\r
+ } else\r
+ return bitrate_str[h_version][h_layer - 1][h_bitrate_index];\r
+ }\r
+\r
+ /**\r
+ * Return Bitrate.\r
+ * \r
+ * @return bitrate in bps and average bitrate for VBR header\r
+ */\r
+ public int bitrate() {\r
+ if (h_vbr == true) {\r
+ return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames))) * 1000;\r
+ } else\r
+ return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
+ }\r
+\r
+ /**\r
+ * Return Instant Bitrate. Bitrate for VBR is not constant.\r
+ * \r
+ * @return bitrate in bps\r
+ */\r
+ public int bitrate_instant() {\r
+ return bitrates[h_version][h_layer - 1][h_bitrate_index];\r
+ }\r
+\r
+ /**\r
+ * Returns Frequency\r
+ * \r
+ * @return frequency string in kHz\r
+ */\r
+ public String sample_frequency_string() {\r
+ switch (h_sample_frequency) {\r
+ case THIRTYTWO:\r
+ if (h_version == MPEG1)\r
+ return "32 kHz";\r
+ else if (h_version == MPEG2_LSF)\r
+ return "16 kHz";\r
+ else\r
+ // SZD\r
+ return "8 kHz";\r
+ case FOURTYFOUR_POINT_ONE:\r
+ if (h_version == MPEG1)\r
+ return "44.1 kHz";\r
+ else if (h_version == MPEG2_LSF)\r
+ return "22.05 kHz";\r
+ else\r
+ // SZD\r
+ return "11.025 kHz";\r
+ case FOURTYEIGHT:\r
+ if (h_version == MPEG1)\r
+ return "48 kHz";\r
+ else if (h_version == MPEG2_LSF)\r
+ return "24 kHz";\r
+ else\r
+ // SZD\r
+ return "12 kHz";\r
+ }\r
+ return (null);\r
+ }\r
+\r
+ /**\r
+ * Returns Mode.\r
+ */\r
+ public String mode_string() {\r
+ switch (h_mode) {\r
+ case STEREO:\r
+ return "Stereo";\r
+ case JOINT_STEREO:\r
+ return "Joint stereo";\r
+ case DUAL_CHANNEL:\r
+ return "Dual channel";\r
+ case SINGLE_CHANNEL:\r
+ return "Single channel";\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Returns Version.\r
+ * \r
+ * @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF\r
+ */\r
+ public String version_string() {\r
+ switch (h_version) {\r
+ case MPEG1:\r
+ return "MPEG-1";\r
+ case MPEG2_LSF:\r
+ return "MPEG-2 LSF";\r
+ case MPEG25_LSF: // SZD\r
+ return "MPEG-2.5 LSF";\r
+ }\r
+ return (null);\r
+ }\r
+\r
+ /**\r
+ * Returns the number of subbands in the current frame.\r
+ * \r
+ * @return number of subbands\r
+ */\r
+ @RETURNLOC("OUT")\r
+ public int number_of_subbands() {\r
+ return h_number_of_subbands;\r
+ }\r
+\r
+ /**\r
+ * Returns Intensity Stereo. (Layer II joint stereo only). Returns the number\r
+ * of subbands which are in stereo mode, subbands above that limit are in\r
+ * intensity stereo mode.\r
+ * \r
+ * @return intensity\r
+ */\r
+ @RETURNLOC("OUT")\r
+ public int intensity_stereo_bound() {\r
+ return h_intensity_stereo_bound;\r
+ }\r