diff options
| author | Björn Stenberg <bjorn@haxx.se> | 2007-01-08 23:53:00 +0000 |
|---|---|---|
| committer | Björn Stenberg <bjorn@haxx.se> | 2007-01-08 23:53:00 +0000 |
| commit | 7039a05147b8bbfc829babea1c65bd436450b505 (patch) | |
| tree | 4ba555eb84ed97b72b0575034d5b0530a393713e /songdbj/javazoom/jl/decoder/Bitstream.java | |
| parent | 6d4c19707ef95942e323cbdc89fbbfdbe45e7cc5 (diff) | |
| download | rockbox-7039a05147b8bbfc829babea1c65bd436450b505.zip rockbox-7039a05147b8bbfc829babea1c65bd436450b505.tar.gz rockbox-7039a05147b8bbfc829babea1c65bd436450b505.tar.bz2 rockbox-7039a05147b8bbfc829babea1c65bd436450b505.tar.xz | |
Splitting out songdbj
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11953 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'songdbj/javazoom/jl/decoder/Bitstream.java')
| -rw-r--r-- | songdbj/javazoom/jl/decoder/Bitstream.java | 655 |
1 files changed, 0 insertions, 655 deletions
diff --git a/songdbj/javazoom/jl/decoder/Bitstream.java b/songdbj/javazoom/jl/decoder/Bitstream.java deleted file mode 100644 index cebbd5b..0000000 --- a/songdbj/javazoom/jl/decoder/Bitstream.java +++ /dev/null @@ -1,655 +0,0 @@ -/* - * 11/19/04 1.0 moved to LGPL. - * - * 11/17/04 Uncomplete frames discarded. E.B, javalayer@javazoom.net - * - * 12/05/03 ID3v2 tag returned. E.B, javalayer@javazoom.net - * - * 12/12/99 Based on Ibitstream. Exceptions thrown on errors, - * Temporary removed seek functionality. mdm@techie.com - * - * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net - * - * 04/14/97 : Added function prototypes for new syncing and seeking - * mechanisms. Also made this file portable. Changes made by Jeff Tsay - * - * @(#) ibitstream.h 1.5, last edit: 6/15/94 16:55:34 - * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) - * @(#) Berlin University of Technology - *----------------------------------------------------------------------- - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as published - * by the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - *---------------------------------------------------------------------- - */ - -package javazoom.jl.decoder; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PushbackInputStream; - - -/** - * The <code>Bistream</code> class is responsible for parsing - * an MPEG audio bitstream. - * - * <b>REVIEW:</b> much of the parsing currently occurs in the - * various decoders. This should be moved into this class and associated - * inner classes. - */ -public final class Bitstream implements BitstreamErrors -{ - /** - * Synchronization control constant for the initial - * synchronization to the start of a frame. - */ - static byte INITIAL_SYNC = 0; - - /** - * Synchronization control constant for non-initial frame - * synchronizations. - */ - static byte STRICT_SYNC = 1; - - // max. 1730 bytes per frame: 144 * 384kbit/s / 32000 Hz + 2 Bytes CRC - /** - * Maximum size of the frame buffer. - */ - private static final int BUFFER_INT_SIZE = 433; - - /** - * The frame buffer that holds the data for the current frame. - */ - private final int[] framebuffer = new int[BUFFER_INT_SIZE]; - - /** - * Number of valid bytes in the frame buffer. - */ - private int framesize; - - /** - * The bytes read from the stream. - */ - private byte[] frame_bytes = new byte[BUFFER_INT_SIZE*4]; - - /** - * Index into <code>framebuffer</code> where the next bits are - * retrieved. - */ - private int wordpointer; - - /** - * Number (0-31, from MSB to LSB) of next bit for get_bits() - */ - private int bitindex; - - /** - * The current specified syncword - */ - private int syncword; - - /** - * Audio header position in stream. - */ - private int header_pos = 0; - - /** - * - */ - private boolean single_ch_mode; - //private int current_frame_number; - //private int last_frame_number; - - private final int bitmask[] = {0, // dummy - 0x00000001, 0x00000003, 0x00000007, 0x0000000F, - 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, - 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, - 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, - 0x0001FFFF }; - - private final PushbackInputStream source; - - private final Header header = new Header(); - - private final byte syncbuf[] = new byte[4]; - - private Crc16[] crc = new Crc16[1]; - - private byte[] rawid3v2 = null; - - private boolean firstframe = true; - - - /** - * Construct a IBitstream that reads data from a - * given InputStream. - * - * @param in The InputStream to read from. - */ - public Bitstream(InputStream in) - { - if (in==null) throw new NullPointerException("in"); - in = new BufferedInputStream(in); - loadID3v2(in); - firstframe = true; - //source = new PushbackInputStream(in, 1024); - source = new PushbackInputStream(in, BUFFER_INT_SIZE*4); - - closeFrame(); - //current_frame_number = -1; - //last_frame_number = -1; - } - - /** - * Return position of the first audio header. - * @return size of ID3v2 tag frames. - */ - public int header_pos() - { - return header_pos; - } - - /** - * Load ID3v2 frames. - * @param in MP3 InputStream. - * @author JavaZOOM - */ - private void loadID3v2(InputStream in) - { - int size = -1; - try - { - // Read ID3v2 header (10 bytes). - in.mark(10); - size = readID3v2Header(in); - header_pos = size; - } - catch (IOException e) - {} - finally - { - try - { - // Unread ID3v2 header (10 bytes). - in.reset(); - } - catch (IOException e) - {} - } - // Load ID3v2 tags. - try - { - if (size > 0) - { - rawid3v2 = new byte[size]; - in.read(rawid3v2,0,rawid3v2.length); - } - } - catch (IOException e) - {} - } - - /** - * Parse ID3v2 tag header to find out size of ID3v2 frames. - * @param in MP3 InputStream - * @return size of ID3v2 frames + header - * @throws IOException - * @author JavaZOOM - */ - private int readID3v2Header(InputStream in) throws IOException - { - byte[] id3header = new byte[4]; - int size = -10; - in.read(id3header,0,3); - // Look for ID3v2 - if ( (id3header[0]=='I') && (id3header[1]=='D') && (id3header[2]=='3')) - { - in.read(id3header,0,3); - int majorVersion = id3header[0]; - int revision = id3header[1]; - in.read(id3header,0,4); - size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]); - } - return (size+10); - } - - /** - * Return raw ID3v2 frames + header. - * @return ID3v2 InputStream or null if ID3v2 frames are not available. - */ - public InputStream getRawID3v2() - { - if (rawid3v2 == null) return null; - else - { - ByteArrayInputStream bain = new ByteArrayInputStream(rawid3v2); - return bain; - } - } - - /** - * Close the Bitstream. - * @throws BitstreamException - */ - public void close() throws BitstreamException - { - try - { - source.close(); - } - catch (IOException ex) - { - throw newBitstreamException(STREAM_ERROR, ex); - } - } - - /** - * Reads and parses the next frame from the input source. - * @return the Header describing details of the frame read, - * or null if the end of the stream has been reached. - */ - public Header readFrame() throws BitstreamException - { - Header result = null; - try - { - result = readNextFrame(); - // E.B, Parse VBR (if any) first frame. - if (firstframe == true) - { - result.parseVBR(frame_bytes); - firstframe = false; - } - } - catch (BitstreamException ex) - { - if ((ex.getErrorCode()==INVALIDFRAME)) - { - // Try to skip this frame. - //System.out.println("INVALIDFRAME"); - try - { - closeFrame(); - result = readNextFrame(); - } - catch (BitstreamException e) - { - if ((e.getErrorCode()!=STREAM_EOF)) - { - // wrap original exception so stack trace is maintained. - throw newBitstreamException(e.getErrorCode(), e); - } - } - } - else if ((ex.getErrorCode()!=STREAM_EOF)) - { - // wrap original exception so stack trace is maintained. - throw newBitstreamException(ex.getErrorCode(), ex); - } - } - return result; - } - - /** - * Read next MP3 frame. - * @return MP3 frame header. - * @throws BitstreamException - */ - private Header readNextFrame() throws BitstreamException - { - if (framesize == -1) - { - nextFrame(); - } - return header; - } - - - /** - * Read next MP3 frame. - * @throws BitstreamException - */ - private void nextFrame() throws BitstreamException - { - // entire frame is read by the header class. - header.read_header(this, crc); - } - - /** - * 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; - } -} |