2 * 11/19/04 1.0 moved to LGPL.
4 * 11/17/04 Uncomplete frames discarded. E.B, javalayer@javazoom.net
6 * 12/05/03 ID3v2 tag returned. E.B, javalayer@javazoom.net
8 * 12/12/99 Based on Ibitstream. Exceptions thrown on errors,
9 * Temporary removed seek functionality. mdm@techie.com
11 * 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net
13 * 04/14/97 : Added function prototypes for new syncing and seeking
14 * mechanisms. Also made this file portable. Changes made by Jeff Tsay
16 * @(#) ibitstream.h 1.5, last edit: 6/15/94 16:55:34
17 * @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
18 * @(#) Berlin University of Technology
19 *-----------------------------------------------------------------------
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU Library General Public License as published
22 * by the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU Library General Public License for more details.
30 * You should have received a copy of the GNU Library General Public
31 * License along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 *----------------------------------------------------------------------
38 * The <code>Bistream</code> class is responsible for parsing
39 * an MPEG audio bitstream.
41 * <b>REVIEW:</b> much of the parsing currently occurs in the
42 * various decoders. This should be moved into this class and associated
45 @LATTICE("FB<F,FF<F,WP<BI,FF*,WP*,BI*")
46 @METHODDEFAULT("OUT<THIS,THIS<VAR,VAR<IN,VAR*,THISLOC=THIS,GLOBALLOC=IN")
47 public final class Bitstream implements BitstreamErrors
50 * Synchronization control constant for the initial
51 * synchronization to the start of a frame.
53 @LOC("F") static byte INITIAL_SYNC = 0;
56 * Synchronization control constant for non-initial frame
60 @LOC("F") static byte STRICT_SYNC = 1;
62 // max. 1730 bytes per frame: 144 * 384kbit/s / 32000 Hz + 2 Bytes CRC
64 * Maximum size of the frame buffer.
66 @LOC("F") private static final int BUFFER_INT_SIZE = 433;
69 * The frame buffer that holds the data for the current frame.
71 @LOC("FB") private final int[] framebuffer = new int[BUFFER_INT_SIZE];
74 * Number of valid bytes in the frame buffer.
76 @LOC("F") private int framesize;
79 * The bytes read from the stream.
81 @LOC("FB") private byte[] frame_bytes = new byte[BUFFER_INT_SIZE*4];
84 * Index into <code>framebuffer</code> where the next bits are
87 @LOC("WP") private int wordpointer;
90 * Number (0-31, from MSB to LSB) of next bit for get_bits()
92 @LOC("BI") private int bitindex;
95 * The current specified syncword
97 @LOC("F") private int syncword;
100 * Audio header position in stream.
102 @LOC("F")private int header_pos = 0;
107 @LOC("F") private boolean single_ch_mode;
108 //private int current_frame_number;
109 //private int last_frame_number;
111 @LOC("F") private final int bitmask[] = {0, // dummy
112 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
113 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
114 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
115 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
118 @LOC("F") private final PushbackInputStream source;
120 @LOC("F") private final Header header = new Header();
122 @LOC("F") private final byte syncbuf[] = new byte[4];
124 @LOC("F") private Crc16[] crc = new Crc16[1];
126 @LOC("F") private byte[] rawid3v2 = null;
128 @LOC("FF") private boolean firstframe = true;
132 * Construct a IBitstream that reads data from a
135 * @param in The InputStream to read from.
137 public Bitstream(InputStream in)
139 if (in==null) throw new NullPointerException("in");
140 in = new BufferedInputStream(in);
143 //source = new PushbackInputStream(in, 1024);
144 source = new PushbackInputStream(in, BUFFER_INT_SIZE*4);
147 //current_frame_number = -1;
148 //last_frame_number = -1;
152 * Return position of the first audio header.
153 * @return size of ID3v2 tag frames.
155 public int header_pos()
162 * @param in MP3 InputStream.
165 private void loadID3v2(InputStream in)
170 // Read ID3v2 header (10 bytes).
172 size = readID3v2Header(in);
175 catch (IOException e)
181 // Unread ID3v2 header (10 bytes).
184 catch (IOException e)
192 rawid3v2 = new byte[size];
193 in.read(rawid3v2,0,rawid3v2.length);
196 catch (IOException e)
201 * Parse ID3v2 tag header to find out size of ID3v2 frames.
202 * @param in MP3 InputStream
203 * @return size of ID3v2 frames + header
204 * @throws IOException
207 private int readID3v2Header(InputStream in) throws IOException
209 byte[] id3header = new byte[4];
211 in.read(id3header,0,3);
213 if ( (id3header[0]=='I') && (id3header[1]=='D') && (id3header[2]=='3'))
215 in.read(id3header,0,3);
216 int majorVersion = id3header[0];
217 int revision = id3header[1];
218 in.read(id3header,0,4);
219 size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]);
225 * Return raw ID3v2 frames + header.
226 * @return ID3v2 InputStream or null if ID3v2 frames are not available.
228 public InputStream getRawID3v2()
230 if (rawid3v2 == null) return null;
233 ByteArrayInputStream bain = new ByteArrayInputStream(rawid3v2);
239 * Close the Bitstream.
240 * @throws BitstreamException
242 public void close() throws BitstreamException
248 catch (IOException ex)
250 throw newBitstreamException(STREAM_ERROR, ex);
255 * Reads and parses the next frame from the input source.
256 * @return the Header describing details of the frame read,
257 * or null if the end of the stream has been reached.
259 public Header readFrame() throws BitstreamException
261 Header result = null;
264 result = readNextFrame();
265 // E.B, Parse VBR (if any) first frame.
266 if (firstframe == true)
268 result.parseVBR(frame_bytes);
272 catch (BitstreamException ex)
274 if ((ex.getErrorCode()==INVALIDFRAME))
276 // Try to skip this frame.
277 //System.out.println("INVALIDFRAME");
281 result = readNextFrame();
283 catch (BitstreamException e)
285 if ((e.getErrorCode()!=STREAM_EOF))
287 // wrap original exception so stack trace is maintained.
288 throw newBitstreamException(e.getErrorCode(), e);
292 else if ((ex.getErrorCode()!=STREAM_EOF))
294 // wrap original exception so stack trace is maintained.
295 throw newBitstreamException(ex.getErrorCode(), ex);
302 * Read next MP3 frame.
303 * @return MP3 frame header.
304 * @throws BitstreamException
306 private Header readNextFrame() throws BitstreamException
317 * Read next MP3 frame.
318 * @throws BitstreamException
320 private void nextFrame() throws BitstreamException
322 // entire frame is read by the header class.
323 header.read_header(this, crc);
327 * Unreads the bytes read from the frame.
328 * @throws BitstreamException
330 // REVIEW: add new error codes for this.
331 public void unreadFrame() throws BitstreamException
333 if (wordpointer==-1 && bitindex==-1 && (framesize>0))
337 source.unread(frame_bytes, 0, framesize);
339 catch (IOException ex)
341 throw newBitstreamException(STREAM_ERROR);
349 public void closeFrame()
357 * Determines if the next 4 bytes of the stream represent a
360 public boolean isSyncCurrentPosition(int syncmode) throws BitstreamException
362 int read = readBytes(syncbuf, 0, 4);
363 int headerstring = ((syncbuf[0] << 24) & 0xFF000000) | ((syncbuf[1] << 16) & 0x00FF0000) | ((syncbuf[2] << 8) & 0x0000FF00) | ((syncbuf[3] << 0) & 0x000000FF);
367 source.unread(syncbuf, 0, read);
369 catch (IOException ex)
373 boolean sync = false;
380 sync = isSyncMark(headerstring, syncmode, syncword);
388 // REVIEW: this class should provide inner classes to
389 // parse the frame contents. Eventually, readBits will
391 public int readBits(int n)
396 public int readCheckedBits(int n)
398 // REVIEW: implement CRC check.
402 protected BitstreamException newBitstreamException(int errorcode)
404 return new BitstreamException(errorcode, null);
406 protected BitstreamException newBitstreamException(int errorcode, Throwable throwable)
408 return new BitstreamException(errorcode, throwable);
412 * Get next 32 bits from bitstream.
413 * They are stored in the headerstring.
414 * syncmod allows Synchro flag ID
415 * The returned value is False at the end of stream.
418 int syncHeader(byte syncmode) throws BitstreamException
422 // read additional 2 bytes
423 int bytesRead = readBytes(syncbuf, 0, 3);
425 if (bytesRead!=3) throw newBitstreamException(STREAM_EOF, null);
427 headerstring = ((syncbuf[0] << 16) & 0x00FF0000) | ((syncbuf[1] << 8) & 0x0000FF00) | ((syncbuf[2] << 0) & 0x000000FF);
433 if (readBytes(syncbuf, 3, 1)!=1)
434 throw newBitstreamException(STREAM_EOF, null);
436 headerstring |= (syncbuf[3] & 0x000000FF);
438 sync = isSyncMark(headerstring, syncmode, syncword);
442 //current_frame_number++;
443 //if (last_frame_number < current_frame_number) last_frame_number = current_frame_number;
448 public boolean isSyncMark(int headerstring, int syncmode, int word)
450 boolean sync = false;
452 if (syncmode == INITIAL_SYNC)
454 //sync = ((headerstring & 0xFFF00000) == 0xFFF00000);
455 sync = ((headerstring & 0xFFE00000) == 0xFFE00000); // SZD: MPEG 2.5
459 sync = ((headerstring & 0xFFF80C00) == word) &&
460 (((headerstring & 0x000000C0) == 0x000000C0) == single_ch_mode);
463 // filter out invalid sample rate
465 sync = (((headerstring >>> 10) & 3)!=3);
466 // filter out invalid layer
468 sync = (((headerstring >>> 17) & 3)!=0);
469 // filter out invalid version
471 sync = (((headerstring >>> 19) & 3)!=1);
477 * Reads the data for the next frame. The frame is not parsed
478 * until parse frame is called.
480 int read_frame_data(int bytesize) throws BitstreamException
483 numread = readFully(frame_bytes, 0, bytesize);
484 framesize = bytesize;
491 * Parses the data previously read with read_frame_data().
493 @LATTICE("GLOBAL<B,B<BNUM,BNUM<K,K<BYTE,BYTE<THIS,B*,K*,THISLOC=THIS,GLOBALLOC=GLOBAL")
494 void parse_frame() throws BitstreamException
496 // Convert Bytes read to int
498 @LOC("BYTE") byte[] byteread = frame_bytes;
499 @LOC("BYTE") int bytesize = framesize;
501 // Check ID3v1 TAG (True only if last frame).
502 //for (int t=0;t<(byteread.length)-2;t++)
504 // if ((byteread[t]=='T') && (byteread[t+1]=='A') && (byteread[t+2]=='G'))
506 // System.out.println("ID3v1 detected at offset "+t);
507 // throw newBitstreamException(INVALIDFRAME, null);
511 for (@LOC("K") int k=0;k<bytesize;k=k+4)
513 @LOC("BYTE") int convert = 0;
514 @LOC("BNUM") byte b0 = 0;
515 @LOC("BNUM") byte b1 = 0;
516 @LOC("BNUM") byte b2 = 0;
517 @LOC("BNUM") byte b3 = 0;
519 if (k+1<bytesize) b1 = byteread[k+1];
520 if (k+2<bytesize) b2 = byteread[k+2];
521 if (k+3<bytesize) b3 = byteread[k+3];
522 framebuffer[b++] = ((b0 << 24) &0xFF000000) | ((b1 << 16) & 0x00FF0000) | ((b2 << 8) & 0x0000FF00) | (b3 & 0x000000FF);
529 * Read bits from buffer into the lower bits of an unsigned int.
530 * The LSB contains the latest read bit of the stream.
531 * (1 <= number_of_bits <= 16)
533 @LATTICE("OUT<RL,RL<THIS,THIS<IN,OUT*,THISLOC=THIS")
535 public int get_bits(@LOC("IN")int number_of_bits)
537 @LOC("OUT") int returnvalue = 0;
538 @LOC("THIS,Bitstream.BI") int sum = bitindex + number_of_bits;
541 // There is a problem here, wordpointer could be -1 ?!
542 if (wordpointer < 0) wordpointer = 0;
547 // all bits contained in *wordpointer
548 returnvalue = (framebuffer[wordpointer] >>> (32 - sum)) & bitmask[number_of_bits];
549 // returnvalue = (wordpointer[0] >> (32 - sum)) & bitmask[number_of_bits];
550 if ((bitindex += number_of_bits) == 32)
553 wordpointer++; // added by me!
558 // E.B : Check that ?
559 //((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0];
560 //wordpointer++; // Added by me!
561 //((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0];
562 @LOC("RL") int Right = (framebuffer[wordpointer] & 0x0000FFFF);
564 @LOC("RL") int Left = (framebuffer[wordpointer] & 0xFFFF0000);
565 returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16)& 0x0000FFFF);
567 returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32 - bitindex))
568 returnvalue &= bitmask[number_of_bits];
574 * Set the word we want to sync the header to.
575 * In Big-Endian byte order
577 void set_syncword(@LOC("IN") int syncword0)
579 syncword = syncword0 & 0xFFFFFF3F;
580 single_ch_mode = ((syncword0 & 0x000000C0) == 0x000000C0);
583 * Reads the exact number of bytes from the source
584 * input stream into a byte array.
586 * @param b The byte array to read the specified number
588 * @param offs The index in the array where the first byte
589 * read should be stored.
590 * @param len the number of bytes to read.
592 * @exception BitstreamException is thrown if the specified
593 * number of bytes could not be read from the stream.
595 @LATTICE("OUT<VAR,VAR<THIS,THIS<IN,IN*,VAR*,THISLOC=THIS")
597 private int readFully(@LOC("OUT") byte[] b, @LOC("IN") int offs, @LOC("IN") int len)
598 throws BitstreamException
600 @LOC("VAR") int nRead = 0;
605 @LOC("IN") int bytesread = source.read(b, offs, len);
613 //throw newBitstreamException(UNEXPECTED_EOF, new EOFException());
615 nRead = nRead + bytesread;
620 catch (IOException ex)
622 throw newBitstreamException(STREAM_ERROR, ex);
628 * Simlar to readFully, but doesn't throw exception when
631 @LATTICE("OUT<VAR,VAR<THIS,THIS<IN,IN*,VAR*,THISLOC=THIS")
633 private int readBytes(@LOC("OUT") byte[] b, @LOC("IN") int offs, @LOC("IN") int len)
634 throws BitstreamException
636 @LOC("VAR") int totalBytesRead = 0;
641 @LOC("IN") int bytesread = source.read(b, offs, len);
646 totalBytesRead += bytesread;
651 catch (IOException ex)
653 throw newBitstreamException(STREAM_ERROR, ex);
655 return totalBytesRead;