/*************************************************************************** * JLayerME is a JAVA library that decodes/plays/converts MPEG 1/2 Layer 3. * Project Homepage: http://www.javazoom.net/javalayer/javalayerme.html. * Copyright (C) JavaZOOM 1999-2005. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *--------------------------------------------------------------------------- * 19 Aug 2004 - Konstantin Belous * Added code for MPEG 2 support * (used the mpglib (http://ftp.tu-clausthal.de/pub/unix/audio/mpg123) as the source for changes). *--------------------------------------------------------------------------- */ package javazoom.jlme.decoder; import java.io.IOException; /** * Description of the Class * * @author micah * @created December 8, 2001 */ public final class Header { public final static int[][] frequencies = { { 22050, 24000, 16000, 1 }, { 44100, 48000, 32000, 1 } }; /** Constant for MPEG-1 version */ public final static int MPEG1 = 1; /** Constant for MPEG-2 version */ public final static int MPEG2 = 0; /** Description of the Field */ public final static int STEREO = 0; /** Description of the Field */ public final static int JOINT_STEREO = 1; /** Description of the Field */ public final static int DUAL_CHANNEL = 2; /** Description of the Field */ public final static int SINGLE_CHANNEL = 3; /** Description of the Field */ public final static int FOURTYFOUR_POINT_ONE = 0; /** Description of the Field */ public final static int FOURTYEIGHT = 1; /** Description of the Field */ public final static int THIRTYTWO = 2; /** Description of the Field */ public final static int bitrates[][][] = { { { 0 /* * free format */ , 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000, 0 }, { 0 /* * free format */ , 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0 }, { 0 /* * free format */ , 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0 } }, { { 0 /* * free format */ , 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0 }, { 0 /* * free format */ , 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0 }, { 0 /* * free format */ , 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0 } } }; /** Description of the Field */ public final static String bitrate_str[][][] = { { { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "forbidden" }, { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" }, { "free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", "forbidden" } }, { { "free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", "320 kbit/s", "352 kbit/s", "384 kbit/s", "416 kbit/s", "448 kbit/s", "forbidden" }, { "free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "384 kbit/s", "forbidden" }, { "free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "forbidden" } } }; public static int framesize; public static int nSlots; private static int h_layer, h_protection_bit, h_bitrate_index, h_padding_bit, h_mode_extension; private static int h_version; private static int h_mode; private static int h_sample_frequency; private static int h_number_of_subbands, h_intensity_stereo_bound; static byte syncmode = BitStream.INITIAL_SYNC; public int version() { return h_version; } public int layer() { return h_layer; } public int bitrate_index() { return h_bitrate_index; } public int sample_frequency() { return h_sample_frequency; } public int frequency() { return frequencies[h_version][h_sample_frequency]; } public int mode() { return h_mode; } public boolean padding() { return (h_padding_bit != 0); } public int slots() { return nSlots; } public int mode_extension() { return h_mode_extension; } public String layer_string() { return "III"; } public String bitrate_string() { return bitrate_str[h_version][h_layer - 1][h_bitrate_index]; } public String sample_frequency_string() { switch (frequencies[h_version][h_sample_frequency]) { case 16000: return "16 kHz"; case 22050: return "22.05 kHz"; case 24000: return "24 kHz"; case 32000: return "32 kHz"; case 44100: return "44.1 kHz"; case 48000: return "48 kHz"; } return "not set"; } public int number_of_subbands() { return h_number_of_subbands; } public int intensity_stereo_bound() { return h_intensity_stereo_bound; } final void read_header(BitStream stream) throws IOException { int headerstring; int channel_bitrate; boolean sync = false; do { headerstring = stream.syncHeader(syncmode); if (syncmode == BitStream.INITIAL_SYNC) { h_version = ((headerstring >>> 19) & 1); if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3) { return; } } h_layer = 4 - (headerstring >>> 17) & 3; // E.B Fix. // h_protection_bit = 0; h_protection_bit = (headerstring >>> 16) & 1; // End. h_bitrate_index = (headerstring >>> 12) & 0xF; h_padding_bit = (headerstring >>> 9) & 1; h_mode = ((headerstring >>> 6) & 3); h_mode_extension = (headerstring >>> 4) & 3; if (h_mode == JOINT_STEREO) { h_intensity_stereo_bound = (h_mode_extension << 2) + 4; } else { h_intensity_stereo_bound = 0; } if (h_layer == 1) { h_number_of_subbands = 32; } else { channel_bitrate = h_bitrate_index; // calculate bitrate per channel: if (h_mode != SINGLE_CHANNEL) { if (channel_bitrate == 4) { channel_bitrate = 1; } else { channel_bitrate -= 4; } } if (h_version == MPEG2) { h_number_of_subbands = 30; } else if ((channel_bitrate == 1) || (channel_bitrate == 2)) { if (h_sample_frequency == THIRTYTWO) { h_number_of_subbands = 12; } else { h_number_of_subbands = 8; } } else if ((h_sample_frequency == FOURTYEIGHT) || ((channel_bitrate >= 3) && (channel_bitrate <= 5))) { h_number_of_subbands = 27; } else { h_number_of_subbands = 30; } } if (h_intensity_stereo_bound > h_number_of_subbands) { h_intensity_stereo_bound = h_number_of_subbands; } // calculate framesize and nSlots calFrameSize(); // read framedata: stream.read_frame_data(framesize); if (stream.isSyncCurrentPosition(syncmode)) { if (syncmode == BitStream.INITIAL_SYNC) { syncmode = BitStream.STRICT_SYNC; stream.set_syncword(headerstring & 0xFFF80CC0); } sync = true; } else { stream.unreadFrame(); } } while (!sync); stream.parse_frame(); } private final void calFrameSize() { if (h_version == MPEG1) { framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) / frequencies[h_version][h_sample_frequency]; } else { framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) / (frequencies[h_version][h_sample_frequency] << 1); } if (h_padding_bit != 0) framesize++; if (h_version == MPEG1) { // E.B Fix nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) - ((h_protection_bit != 0) ? 0 : 2) - 4; } else { nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) - ((h_protection_bit != 0) ? 0 : 2) - 4; } framesize -= 4; } }