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

📄 bitstream.java

📁 JLayer is a library that decodes/plays/converts MPEG 1/2/2.5 Layer 1/2/3 (i.e. MP3) in real time fo
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	}

	/**
	 * Unreads the bytes read from the frame.
	 * @throws BitstreamException
	 */
	// REVIEW: add new error codes for this.
	public void unreadFrame() throws BitstreamException
	{
		if (wordpointer==-1 && bitindex==-1 && (framesize>0))
		{
			try
			{
				source.unread(frame_bytes, 0, framesize);
			}
			catch (IOException ex)
			{
				throw newBitstreamException(STREAM_ERROR);
			}
		}
	}

	/**
	 * Close MP3 frame.
	 */
	public void closeFrame()
	{
		framesize = -1;
		wordpointer = -1;
		bitindex = -1;
	}

	/**
	 * Determines if the next 4 bytes of the stream represent a
	 * frame header.
	 */
	public boolean isSyncCurrentPosition(int syncmode) throws BitstreamException
	{
		int read = readBytes(syncbuf, 0, 4);
		int headerstring = ((syncbuf[0] << 24) & 0xFF000000) | ((syncbuf[1] << 16) & 0x00FF0000) | ((syncbuf[2] << 8) & 0x0000FF00) | ((syncbuf[3] << 0) & 0x000000FF);

		try
		{
			source.unread(syncbuf, 0, read);
		}
		catch (IOException ex)
		{
		}

		boolean sync = false;
		switch (read)
		{
			case 0:
				sync = true;
				break;
			case 4:
				sync = isSyncMark(headerstring, syncmode, syncword);
				break;
		}

		return sync;
	}


	// REVIEW: this class should provide inner classes to
	// parse the frame contents. Eventually, readBits will
	// be removed.
	public int readBits(int n)
	{
		return get_bits(n);
	}

	public int readCheckedBits(int n)
	{
		// REVIEW: implement CRC check.
		return get_bits(n);
	}

	protected BitstreamException newBitstreamException(int errorcode)
	{
		return new BitstreamException(errorcode, null);
	}
	protected BitstreamException newBitstreamException(int errorcode, Throwable throwable)
	{
		return new BitstreamException(errorcode, throwable);
	}

  /**
   * Get next 32 bits from bitstream.
   * They are stored in the headerstring.
   * syncmod allows Synchro flag ID
   * The returned value is False at the end of stream.
   */

	int syncHeader(byte syncmode) throws BitstreamException
	{
		boolean sync;
		int headerstring;
		// read additional 2 bytes
		int bytesRead = readBytes(syncbuf, 0, 3);

		if (bytesRead!=3) throw newBitstreamException(STREAM_EOF, null);

		headerstring = ((syncbuf[0] << 16) & 0x00FF0000) | ((syncbuf[1] << 8) & 0x0000FF00) | ((syncbuf[2] << 0) & 0x000000FF);

		do
		{
			headerstring <<= 8;

			if (readBytes(syncbuf, 3, 1)!=1)
				throw newBitstreamException(STREAM_EOF, null);

			headerstring |= (syncbuf[3] & 0x000000FF);

			sync = isSyncMark(headerstring, syncmode, syncword);
		}
		while (!sync);

		//current_frame_number++;
		//if (last_frame_number < current_frame_number) last_frame_number = current_frame_number;

		return headerstring;
	}

	public boolean isSyncMark(int headerstring, int syncmode, int word)
	{
		boolean sync = false;

		if (syncmode == INITIAL_SYNC)
		{
			//sync =  ((headerstring & 0xFFF00000) == 0xFFF00000);
			sync =  ((headerstring & 0xFFE00000) == 0xFFE00000);	// SZD: MPEG 2.5
		}
		else
		{
			sync =  ((headerstring & 0xFFF80C00) == word) &&
			    (((headerstring & 0x000000C0) == 0x000000C0) == single_ch_mode);
		}

		// filter out invalid sample rate
		if (sync)
			sync = (((headerstring >>> 10) & 3)!=3);
		// filter out invalid layer
		if (sync)
			sync = (((headerstring >>> 17) & 3)!=0);
		// filter out invalid version
		if (sync)
			sync = (((headerstring >>> 19) & 3)!=1);

		return sync;
	}

	/**
	 * Reads the data for the next frame. The frame is not parsed
	 * until parse frame is called.
	 */
	int read_frame_data(int bytesize) throws BitstreamException
	{
 		int	numread = 0;
		numread = readFully(frame_bytes, 0, bytesize);
		framesize = bytesize;
		wordpointer = -1;
	    bitindex = -1;
	    return numread;
	}

  /**
   * Parses the data previously read with read_frame_data().
   */
  void parse_frame() throws BitstreamException
  {
	// Convert Bytes read to int
	int	b=0;
	byte[] byteread = frame_bytes;
	int bytesize = framesize;

	// Check ID3v1 TAG (True only if last frame).
	//for (int t=0;t<(byteread.length)-2;t++)
	//{
	//	if ((byteread[t]=='T') && (byteread[t+1]=='A') && (byteread[t+2]=='G'))
	//	{
	//		System.out.println("ID3v1 detected at offset "+t);
	//		throw newBitstreamException(INVALIDFRAME, null);
	//	} 	
	//}
	
	for (int k=0;k<bytesize;k=k+4)
	{
		int convert = 0;
		byte b0 = 0;
		byte b1 = 0;
		byte b2 = 0;
		byte b3 = 0;
		b0 = byteread[k];
		if (k+1<bytesize) b1 = byteread[k+1];
		if (k+2<bytesize) b2 = byteread[k+2];
		if (k+3<bytesize) b3 = byteread[k+3];
		framebuffer[b++] = ((b0 << 24) &0xFF000000) | ((b1 << 16) & 0x00FF0000) | ((b2 << 8) & 0x0000FF00) | (b3 & 0x000000FF);
	}
	wordpointer = 0;
    bitindex = 0;
  }

  /**
   * Read bits from buffer into the lower bits of an unsigned int.
   * The LSB contains the latest read bit of the stream.
   * (1 <= number_of_bits <= 16)
   */
  public int get_bits(int number_of_bits)
  {
  	int				returnvalue = 0;
  	int 			sum = bitindex + number_of_bits;

	// E.B
	// There is a problem here, wordpointer could be -1 ?!
    if (wordpointer < 0) wordpointer = 0;
    // E.B : End.

  	if (sum <= 32)
  	{
	   // all bits contained in *wordpointer
	   returnvalue = (framebuffer[wordpointer] >>> (32 - sum)) & bitmask[number_of_bits];
	   // returnvalue = (wordpointer[0] >> (32 - sum)) & bitmask[number_of_bits];
	   if ((bitindex += number_of_bits) == 32)
	   {
		 bitindex = 0;
		 wordpointer++; // added by me!
	   }
	   return returnvalue;
    }

    // E.B : Check that ?
    //((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0];
    //wordpointer++; // Added by me!
    //((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0];
	int Right = (framebuffer[wordpointer] & 0x0000FFFF);
	wordpointer++;
	int Left = (framebuffer[wordpointer] & 0xFFFF0000);
	returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16)& 0x0000FFFF);

    returnvalue >>>= 48 - sum;	// returnvalue >>= 16 - (number_of_bits - (32 - bitindex))
    returnvalue &= bitmask[number_of_bits];
    bitindex = sum - 32;
    return returnvalue;
}

	/**
	 * Set the word we want to sync the header to.
	 * In Big-Endian byte order
	 */
	void set_syncword(int syncword0)
	{
		syncword = syncword0 & 0xFFFFFF3F;
		single_ch_mode = ((syncword0 & 0x000000C0) == 0x000000C0);
	}
	/**
	 * Reads the exact number of bytes from the source
	 * input stream into a byte array.
	 *
	 * @param b		The byte array to read the specified number
	 *				of bytes into.
	 * @param offs	The index in the array where the first byte
	 *				read should be stored.
	 * @param len	the number of bytes to read.
	 *
	 * @exception BitstreamException is thrown if the specified
	 *		number of bytes could not be read from the stream.
	 */
	private int readFully(byte[] b, int offs, int len)
		throws BitstreamException
	{		
		int nRead = 0;
		try
		{
			while (len > 0)
			{
				int bytesread = source.read(b, offs, len);
				if (bytesread == -1)
				{
					while (len-->0)
					{
						b[offs++] = 0;
					}
					break;
					//throw newBitstreamException(UNEXPECTED_EOF, new EOFException());
				}
				nRead = nRead + bytesread;
				offs += bytesread;
				len -= bytesread;
			}
		}
		catch (IOException ex)
		{
			throw newBitstreamException(STREAM_ERROR, ex);
		}
		return nRead;
	}

	/**
	 * Simlar to readFully, but doesn't throw exception when
	 * EOF is reached.
	 */
	private int readBytes(byte[] b, int offs, int len)
		throws BitstreamException
	{
		int totalBytesRead = 0;
		try
		{
			while (len > 0)
			{
				int bytesread = source.read(b, offs, len);
				if (bytesread == -1)
				{
					break;
				}
				totalBytesRead += bytesread;
				offs += bytesread;
				len -= bytesread;
			}
		}
		catch (IOException ex)
		{
			throw newBitstreamException(STREAM_ERROR, ex);
		}
		return totalBytesRead;
	}
}

⌨️ 快捷键说明

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