Uses 119K of libraries. Click here for Pure Java version (5137L/31K).
1 | lib 1400511 // VorbisJava (to unpack ogg file) |
2 | |
3 | import org.gagravarr.ogg.*; |
4 | |
5 | // replaces OggPacketReader |
6 | sclass OggStreamPacketReader { |
7 | bool newMechanism; // slightly more efficient but not working yet (TODO) |
8 | InputStream inp; |
9 | Iterator<OggPacketData> it; |
10 | OggPacket nextPacket; |
11 | |
12 | *(InputStream *inp, bool *newMechanism) {} |
13 | *(InputStream *inp) {} |
14 | |
15 | /** |
16 | * Returns the next packet in the file, or |
17 | * null if no more packets remain. |
18 | * Call {@link OggPacket#isBeginningOfStream()} |
19 | * to detect if it is the first packet in the |
20 | * stream or not, and use |
21 | * {@link OggPacket#getSid()} to track which |
22 | * stream it belongs to. |
23 | */ |
24 | public OggPacket getNextPacket() throws IOException { |
25 | // If we skipped to a point in the stream, and |
26 | // have a packet waiting, return that |
27 | if(nextPacket != null) { |
28 | OggPacket p = nextPacket; |
29 | nextPacket = null; |
30 | return p; |
31 | } |
32 | |
33 | // If we're already part way through a page, |
34 | // then fetch the next packet. If it's a |
35 | // full one, then we're done. |
36 | OggPacketData leftOver = null; |
37 | if(it != null && it.hasNext()) { |
38 | OggPacketData packet = it.next(); |
39 | if(packet instanceof OggPacket) { |
40 | return (OggPacket)packet; |
41 | } |
42 | leftOver = packet; |
43 | } |
44 | |
45 | // Find the next page, from which |
46 | // to get our next packet from |
47 | int searched = 0; |
48 | int pos = -1; |
49 | boolean found = false; |
50 | int r; |
51 | while (searched < 65536 && !found) { |
52 | r = inp.read(); |
53 | if(r == -1) { |
54 | // No more data |
55 | return null; |
56 | } |
57 | |
58 | switch(pos) { |
59 | case -1: |
60 | if(r == (int)'O') { |
61 | pos = 0; |
62 | } |
63 | break; |
64 | case 0: |
65 | if(r == (int)'g') { |
66 | pos = 1; |
67 | } else { |
68 | pos = -1; |
69 | } |
70 | break; |
71 | case 1: |
72 | if(r == (int)'g') { |
73 | pos = 2; |
74 | } else { |
75 | pos = -1; |
76 | } |
77 | break; |
78 | case 2: |
79 | if(r == (int)'S') { |
80 | found = true; |
81 | } else { |
82 | pos = -1; |
83 | } |
84 | break; |
85 | } |
86 | |
87 | if(!found) { |
88 | searched++; |
89 | } |
90 | } |
91 | |
92 | if(!found) { |
93 | throw new IOException("Next ogg packet header not found after searching " + searched + " bytes"); |
94 | } |
95 | |
96 | searched -= 3; // OggS |
97 | if(searched > 0) { |
98 | System.err.println("Warning - had to skip " + searched + " bytes of junk data before finding the next packet header"); |
99 | } |
100 | |
101 | // Create the page, and prime the iterator on it |
102 | |
103 | macro doIt { |
104 | if (!page.isChecksumValid()) { |
105 | warn("invalid checksum on page " + |
106 | page.getSequenceNumber() + " of stream " + |
107 | Integer.toHexString(page.getSid()) + " (" + |
108 | page.getSid() + ")"); |
109 | } |
110 | it = page.getPacketIterator(leftOver); |
111 | } |
112 | |
113 | if (newMechanism) { |
114 | OggStreamPage page = new(inp); |
115 | doIt |
116 | } else { |
117 | OggPage page = new(inp) {}; |
118 | doIt |
119 | } |
120 | return getNextPacket(); |
121 | } |
122 | |
123 | /** |
124 | * Returns the next packet with the given SID (Stream ID), or |
125 | * null if no more packets remain. |
126 | * Any packets from other streams will be silently discarded. |
127 | */ |
128 | public OggPacket getNextPacketWithSid(int sid) throws IOException { |
129 | OggPacket p = null; |
130 | while( (p = getNextPacket()) != null ) { |
131 | if(p.getSid() == sid) { |
132 | return p; |
133 | } |
134 | } |
135 | return null; |
136 | } |
137 | |
138 | /** |
139 | * Un-reads a packet, leaving it ready to be feteched by the |
140 | * next call to {@link #getNextPacket()}. |
141 | * Only one packet may be unread. |
142 | * Normally used when identifying a stream, to leave the |
143 | * initial packet ready for a decoder |
144 | */ |
145 | public void unreadPacket(OggPacket packet) { |
146 | if(nextPacket != null) { |
147 | throw new IllegalStateException("Can't un-read twice"); |
148 | } |
149 | nextPacket = packet; |
150 | } |
151 | |
152 | /** |
153 | * Skips forward until the first packet with a Sequence Number |
154 | * of equal or greater than that specified. Call {@link #getNextPacket()} |
155 | * to retrieve this packet. |
156 | * This method advances across all streams, but only searches the |
157 | * specified one. |
158 | * @param sid The ID of the stream who's packets we will search |
159 | * @param sequenceNumber The sequence number we're looking for |
160 | */ |
161 | public void skipToSequenceNumber(int sid, int sequenceNumber) throws IOException { |
162 | OggPacket p = null; |
163 | while( (p = getNextPacket()) != null ) { |
164 | if(p.getSid() == sid && p.getSequenceNumber() >= sequenceNumber) { |
165 | nextPacket = p; |
166 | break; |
167 | } |
168 | } |
169 | } |
170 | |
171 | /** |
172 | * Skips forward until the first packet with a Granule Position |
173 | * of equal or greater than that specified. Call {@link #getNextPacket()} |
174 | * to retrieve this packet. |
175 | * This method advances across all streams, but only searches the |
176 | * specified one. |
177 | * @param sid The ID of the stream who's packets we will search |
178 | * @param granulePosition The granule position we're looking for |
179 | */ |
180 | public void skipToGranulePosition(int sid, long granulePosition) throws IOException { |
181 | OggPacket p = null; |
182 | while( (p = getNextPacket()) != null ) { |
183 | if(p.getSid() == sid && p.getGranulePosition() >= granulePosition) { |
184 | nextPacket = p; |
185 | break; |
186 | } |
187 | } |
188 | } |
189 | } |
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1032910 |
Snippet name: | OggStreamPacketReader |
Eternal ID of this version: | #1032910/8 |
Text MD5: | d1dc47678301589c5ef8757b0456a89e |
Transpilation MD5: | d685c7f3c9a5bccfaf459339f67ddaf2 |
Author: | stefan |
Category: | javax / audio |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-10-10 21:45:02 |
Source code size: | 5768 bytes / 189 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 171 / 291 |
Version history: | 7 change(s) |
Referenced in: | [show references] |