lib 1400511 // VorbisJava (to unpack ogg file) import org.gagravarr.ogg.*; // replaces OggPacketReader sclass OggStreamPacketReader_v2 { InputStream inp; Iterator it; OggStreamPacket nextPacket; *(InputStream *inp) {} /** * Returns the next packet in the file, or * null if no more packets remain. * Call {@link OggStreamPacket#isBeginningOfStream()} * to detect if it is the first packet in the * stream or not, and use * {@link OggStreamPacket#getSid()} to track which * stream it belongs to. */ public OggStreamPacket getNextPacket() throws IOException { // If we skipped to a point in the stream, and // have a packet waiting, return that if(nextPacket != null) { OggStreamPacket p = nextPacket; nextPacket = null; return p; } // If we're already part way through a page, // then fetch the next packet. If it's a // full one, then we're done. OggPacketData leftOver = null; if(it != null && it.hasNext()) { OggPacketData packet = it.next(); if(packet instanceof OggStreamPacket) { return (OggStreamPacket)packet; } leftOver = packet; } // Find the next page, from which // to get our next packet from int searched = 0; int pos = -1; boolean found = false; int r; while (searched < 65536 && !found) { r = inp.read(); if(r == -1) { // No more data return null; } switch(pos) { case -1: if(r == (int)'O') { pos = 0; } break; case 0: if(r == (int)'g') { pos = 1; } else { pos = -1; } break; case 1: if(r == (int)'g') { pos = 2; } else { pos = -1; } break; case 2: if(r == (int)'S') { found = true; } else { pos = -1; } break; } if(!found) { searched++; } } if(!found) { throw new IOException("Next ogg packet header not found after searching " + searched + " bytes"); } searched -= 3; // OggS if(searched > 0) { System.err.println("Warning - had to skip " + searched + " bytes of junk data before finding the next packet header"); } // Create the page, and prime the iterator on it OggStreamPage page = new(inp); if (!page.isChecksumValid()) { warn("invalid checksum on page " + page.getSequenceNumber() + " of stream " + Integer.toHexString(page.getSid()) + " (" + page.getSid() + ")"); } it = page.getPacketIterator(leftOver); return getNextPacket(); } /** * Returns the next packet with the given SID (Stream ID), or * null if no more packets remain. * Any packets from other streams will be silently discarded. */ public OggStreamPacket getNextPacketWithSid(int sid) throws IOException { OggStreamPacket p = null; while( (p = getNextPacket()) != null ) { if(p.getSid() == sid) { return p; } } return null; } /** * Un-reads a packet, leaving it ready to be feteched by the * next call to {@link #getNextPacket()}. * Only one packet may be unread. * Normally used when identifying a stream, to leave the * initial packet ready for a decoder */ public void unreadPacket(OggStreamPacket packet) { if(nextPacket != null) { throw new IllegalStateException("Can't un-read twice"); } nextPacket = packet; } /** * Skips forward until the first packet with a Sequence Number * of equal or greater than that specified. Call {@link #getNextPacket()} * to retrieve this packet. * This method advances across all streams, but only searches the * specified one. * @param sid The ID of the stream who's packets we will search * @param sequenceNumber The sequence number we're looking for */ public void skipToSequenceNumber(int sid, int sequenceNumber) throws IOException { OggStreamPacket p = null; while( (p = getNextPacket()) != null ) { if(p.getSid() == sid && p.getSequenceNumber() >= sequenceNumber) { nextPacket = p; break; } } } /** * Skips forward until the first packet with a Granule Position * of equal or greater than that specified. Call {@link #getNextPacket()} * to retrieve this packet. * This method advances across all streams, but only searches the * specified one. * @param sid The ID of the stream who's packets we will search * @param granulePosition The granule position we're looking for */ public void skipToGranulePosition(int sid, long granulePosition) throws IOException { OggStreamPacket p = null; while( (p = getNextPacket()) != null ) { if(p.getSid() == sid && p.getGranulePosition() >= granulePosition) { nextPacket = p; break; } } } }