⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp3framereader.java

📁 项目描述: Fluid is a server daemon for streaming media. The latest release is built as an API for buil
💻 JAVA
字号:
package streams.mp3;import java.io.*;import common.Bitmask;import common.Delay;/** * A helper class for reading individual frames from an * MP3 input stream. * <P> * For each frame the header is first read to determine * the framesize as well as the delay. Other information * such as the type, layer, bitrate and sampling frequency * is extracted in the process as well. * * @author Lars Samuelsson */public class MP3FrameReader {    /**     * MPEG 1 type     */    public static final int MPEG1  = 3;    /**     * MPEG 2 type     */    public static final int MPEG2  = 2;    /**     * MPEG 2.5 type     */    public static final int MPEG25 = 0;    /**     * Layer I type     */    public static final int LAYERI = 3;    /**     * Layer II type     */    public static final int LAYERII = 2;    /**     * Layer III type     */    public static final int LAYERIII = 1;    // bitrate lookup table (0 free, -1 bad) kbit/s    private int[][] bitrates =    {	{-1,   0,   0,   0,  -1,   0,   0,   0},	{-1,   8,  32,  32,  -1,  32,  32,  32},	{-1,  16,  48,  64,  -1,  40,  48,  64},	{-1,  24,  56,  96,  -1,  48,  56,  96},	{-1,  32,  64, 128,  -1,  56,  64, 128},	{-1,  64,  80, 160,  -1,  64,  80, 160},	{-1,  80,  96, 192,  -1,  80,  96, 192},	{-1,  56, 112, 224,  -1,  96, 112, 224},	{-1,  64, 128, 256,  -1, 112, 128, 256},	{-1, 128, 160, 288,  -1, 128, 160, 288},	{-1, 160, 192, 320,  -1, 160, 192, 320},	{-1, 112, 224, 352,  -1, 192, 224, 352},	{-1, 128, 256, 384,  -1, 224, 256, 384},	{-1, 256, 320, 416,  -1, 256, 320, 416},	{-1, 320, 384, 448,  -1, 320, 384, 448},	{-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1}    };    // frequency lookup (-1 bad)    private int frequencies[][] =    {	{11025,    -1, 22050, 44100},	{12000,    -1, 24000, 48000},	{ 8000,    -1, 16000, 32000},	{   -1,    -1,    -1,     -1}    };    private final int headerlength = 4;    private byte[] header;    private final int framesync = 2047;    private int framesize, bitrate, frequency, type, layer;    private Delay delay;    private InputStream mp3input;    /**     * Creates a frame reader on the specified input stream.     *     * @param mp3input An input stream containing MP3 data     */    public MP3FrameReader(InputStream mp3input) {	this.mp3input = mp3input;    }    /**     * Reads the next frame from the input stream until     * the file ends or garbled data is found.     *     * The tag is considered garbled data as it has     * nothing to do in a continous stream of MP3 frames.     *     * @return An MP3 frame or null if the end of the     *         file or a tag has been reached     */    public byte[] nextFrame() throws IOException {	   byte[] frame = null;      scanForSynch();      byte[] fakeHeader = read(headerlength-1);	   if(fakeHeader == null) {         return null;	   }      header = new byte[fakeHeader.length + 1];      header[0] = (byte)255;      for (int i = 0; i < fakeHeader.length; i++) {         header[i+1] = fakeHeader[i];      }	   try {         if(decodeHeader(header)) {		      int datasize = framesize - header.length;		      frame = new byte[framesize];		      System.arraycopy(header, 0, frame, 0, header.length);		      if(mp3input.read(frame, header.length, datasize) == -1)               return null;         }	   } catch(Exception e) {	      return null;  // garbled data	   }	   return frame;    }    public void scanForSynch () throws IOException {      int b = -1;      while (((b = mp3input.read()) != 255) && (b != -1)) {         //System.out.println("b: " + b);      }    }    /**     * Reads the given number of bytes from the stream.     *     * @param len The number of bytes to be read     * @return    The read bytes     */    public byte[] read(int len) throws IOException {	byte[] bytes = new byte[len];	mp3input.read(bytes);	return bytes;    }    /**     * Extracts type, layer, bitrate, frequency, framesize and     * delay from the header.     * <P>     * <B>Header bits</B><BR>     * <TABLE><TR>     * <TD Align="Right"> 31 - 21 </TD>     * <TD Align="Left"> frame sync (all set in a valid frame)</TD></TR>     * <TD Align="Right"> 20 - 19 </TD>     * <TD Align="Left"> MPEG audio version </TD></TR>     * <TD Align="Right"> 18 - 17 </TD>     * <TD Align="Left"> layer description </TD></TR>     * <TD Align="Right"> 16 </TD>     * <TD Align="Left"> protection bit </TD></TR>     * <TD Align="Right"> 15 - 12 </TD>     * <TD Align="Left"> bitrate index </TD></TR>     * <TD Align="Right"> 11 - 10 </TD>     * <TD Align="Left"> sampling rate frequency index </TD></TR>     * <TD Align="Right"> 09 </TD>     * <TD Align="Left"> padding bit </TD></TR>     * <TD Align="Right"> 08 </TD>     * <TD Align="Left"> private bit </TD></TR>     * <TD Align="Right"> 07 - 06 </TD>     * <TD Align="Left"> channel mode </TD></TR>     * <TD Align="Right"> 05 - 04 </TD>     * <TD Align="Left"> mode extension </TD></TR>     * <TD Align="Right"> 03 </TD>     * <TD Align="Left"> copyright bit </TD></TR>     * <TD Align="Right"> 02 </TD>     * <TD Align="Left"> original indication bit </TD></TR>     * <TD Align="Right"> 01 - 00 </TD>     * <TD Align="Left"> emphasis </TD></TR>     * </TABLE>     *     * @param headerBytes A frame header to be decoded     * @return            true if this header could be decoded     */    public boolean decodeHeader(byte[] headerBytes) {	int x, y, pad;	Bitmask header = new Bitmask(headerBytes);	// all 11 bits are set in a valid frame	if (header.get(21, 31) != framesync) {		// System.out.println("[FrameReader]:  Framesync failure.");	    return false;	}	type = header.get(19, 20);	layer = header.get(17, 18);	x = ((type & 0x01) << 2) + layer;	y = header.get(12, 15);	if(bitrates[y][x] < 0) {		System.out.println("[FrameReader]:  Bitrate failure.");	    return false;	}	bitrate = bitrates[y][x];	x = type;	y = header.get(10, 11);	if(frequencies[y][x] < 0) {		System.out.println("[FrameReader]:  Frequency failure.");	    return false;	}	frequency = frequencies[y][x];	pad = header.get(9);    //  System.out.print("Padding: "+pad);	if(layer == LAYERI)	    framesize = (12 * bitrate * 1000 / frequency + pad) * 4;	else	    framesize = 144 * bitrate * 1000 / frequency + pad;	// delay = new Delay((double) framesize * (double) 8 / (double) bitrate * (double) 1000 / (double) 1024);    // Matt's new non-messed delay calc, sorry about the retarded # of (double)s    delay = new Delay((double)framesize * 8 * 1000 / bitrate / 1000);    // System.out.println("Framesize: "+framesize+", Bitrate: "+bitrate+", Delay: "+delay.getMillis()+":"+delay.getNanos());	return true;    }    /**     * Fetches the bitrate based on the last header read     *     * @return The current bitrate     */    public int getBitrate() {	return bitrate;    }    /**     * Fetches the frequency based on the last header read     *     * @return The current frequency     */    public int getFrequency() {	return frequency;    }    /**     * Fetches the type based on the last header read     *     * @return The current type     */    public int getType() {	return type;    }    /**     * Fetches the layer based on the last header read     *     * @return The current layer     */    public int getLayer() {	return layer;    }    /**     * Fetches the delay based on the last header read     *     * @return The current delay     */    public Delay getDelay() {	return delay;    }    /**     * Fetches the frame size based on the last header read     *     * @return The current frame size     */    public int getFrameSize() {	return framesize;    }    /**     * Fetches the last read header as an array of bytes     *     * @return the last read header     */    public byte[] getHeader() {	return header;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -