diff options
author | Michiel Van Der Kolk <not.valid@email.address> | 2005-07-11 15:42:37 +0000 |
---|---|---|
committer | Michiel Van Der Kolk <not.valid@email.address> | 2005-07-11 15:42:37 +0000 |
commit | 9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e (patch) | |
tree | 4c304cd4151020bd5494d279ee68a105ae3a5a3a /songdbj/org/tritonus/lowlevel/pogg | |
parent | dfa8ecbe609ca8ea194d08560a44fb9a92e94b4b (diff) | |
download | rockbox-9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e.tar.gz rockbox-9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e.zip |
Songdb java version, source. only 1.5 compatible
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7101 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'songdbj/org/tritonus/lowlevel/pogg')
-rw-r--r-- | songdbj/org/tritonus/lowlevel/pogg/Buffer.java | 284 | ||||
-rw-r--r-- | songdbj/org/tritonus/lowlevel/pogg/Ogg.java | 104 | ||||
-rw-r--r-- | songdbj/org/tritonus/lowlevel/pogg/Packet.java | 133 | ||||
-rw-r--r-- | songdbj/org/tritonus/lowlevel/pogg/Page.java | 298 | ||||
-rw-r--r-- | songdbj/org/tritonus/lowlevel/pogg/StreamState.java | 703 | ||||
-rw-r--r-- | songdbj/org/tritonus/lowlevel/pogg/SyncState.java | 339 | ||||
-rw-r--r-- | songdbj/org/tritonus/lowlevel/pogg/package.html | 12 |
7 files changed, 1873 insertions, 0 deletions
diff --git a/songdbj/org/tritonus/lowlevel/pogg/Buffer.java b/songdbj/org/tritonus/lowlevel/pogg/Buffer.java new file mode 100644 index 0000000000..6d94c37740 --- /dev/null +++ b/songdbj/org/tritonus/lowlevel/pogg/Buffer.java | |||
@@ -0,0 +1,284 @@ | |||
1 | /* | ||
2 | * Buffer.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 2000 - 2005 by Matthias Pfisterer | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU Library General Public License as published | ||
12 | * by the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU Library General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU Library General Public | ||
21 | * License along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | |<--- this code is formatted to fit into 80 columns --->| | ||
27 | */ | ||
28 | |||
29 | package org.tritonus.lowlevel.pogg; | ||
30 | |||
31 | import java.io.UnsupportedEncodingException; | ||
32 | |||
33 | import org.tritonus.share.TDebug; | ||
34 | |||
35 | |||
36 | /** Wrapper for oggpack_buffer. | ||
37 | */ | ||
38 | public class Buffer | ||
39 | { | ||
40 | static | ||
41 | { | ||
42 | Ogg.loadNativeLibrary(); | ||
43 | if (TDebug.TraceOggNative) | ||
44 | { | ||
45 | setTrace(true); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | |||
50 | /** | ||
51 | * Holds the pointer to oggpack_buffer | ||
52 | * for the native code. | ||
53 | * This must be long to be 64bit-clean. | ||
54 | */ | ||
55 | private long m_lNativeHandle; | ||
56 | |||
57 | |||
58 | |||
59 | public Buffer() | ||
60 | { | ||
61 | if (TDebug.TraceOggNative) { TDebug.out("Buffer.<init>(): begin"); } | ||
62 | int nReturn = malloc(); | ||
63 | if (nReturn < 0) | ||
64 | { | ||
65 | throw new RuntimeException("malloc of ogg_page failed"); | ||
66 | } | ||
67 | if (TDebug.TraceOggNative) { TDebug.out("Buffer.<init>(): end"); } | ||
68 | } | ||
69 | |||
70 | |||
71 | |||
72 | public void finalize() | ||
73 | { | ||
74 | // TODO: call free() | ||
75 | // call super.finalize() first or last? | ||
76 | // and introduce a flag if free() has already been called? | ||
77 | } | ||
78 | |||
79 | |||
80 | |||
81 | private native int malloc(); | ||
82 | public native void free(); | ||
83 | |||
84 | |||
85 | /** Calls oggpack_writeinit(). | ||
86 | */ | ||
87 | public native void writeInit(); | ||
88 | |||
89 | |||
90 | /** Calls oggpack_writetrunc(). | ||
91 | */ | ||
92 | public native void writeTrunc(int nBits); | ||
93 | |||
94 | |||
95 | /** Calls oggpack_writealign(). | ||
96 | */ | ||
97 | public native void writeAlign(); | ||
98 | |||
99 | |||
100 | /** Calls oggpack_writecopy(). | ||
101 | */ | ||
102 | public native void writeCopy(byte[] abSource, int nBits); | ||
103 | |||
104 | |||
105 | /** Calls oggpack_reset(). | ||
106 | */ | ||
107 | public native void reset(); | ||
108 | |||
109 | |||
110 | /** Calls oggpack_writeclear(). | ||
111 | */ | ||
112 | public native void writeClear(); | ||
113 | |||
114 | |||
115 | /** Calls oggpack_readinit(). | ||
116 | */ | ||
117 | public native void readInit(byte[] abBuffer, int nBytes); | ||
118 | |||
119 | |||
120 | /** Calls oggpack_write(). | ||
121 | */ | ||
122 | public native void write(int nValue, int nBits); | ||
123 | |||
124 | |||
125 | /** Calls oggpack_look(). | ||
126 | */ | ||
127 | public native int look(int nBits); | ||
128 | |||
129 | |||
130 | /** Calls oggpack_look1(). | ||
131 | */ | ||
132 | public native int look1(); | ||
133 | |||
134 | |||
135 | /** Calls oggpack_adv(). | ||
136 | */ | ||
137 | public native void adv(int nBits); | ||
138 | |||
139 | |||
140 | /** Calls oggpack_adv1(). | ||
141 | */ | ||
142 | public native void adv1(); | ||
143 | |||
144 | |||
145 | /** Calls oggpack_read(). | ||
146 | */ | ||
147 | public native int read(int nBits); | ||
148 | |||
149 | |||
150 | /** Calls oggpack_read1(). | ||
151 | */ | ||
152 | public native int read1(); | ||
153 | |||
154 | |||
155 | /** Calls oggpack_bytes(). | ||
156 | */ | ||
157 | public native int bytes(); | ||
158 | |||
159 | |||
160 | /** Calls oggpack_bits(). | ||
161 | */ | ||
162 | public native int bits(); | ||
163 | |||
164 | |||
165 | /** Calls oggpack_get_buffer(). | ||
166 | */ | ||
167 | public native byte[] getBuffer(); | ||
168 | |||
169 | |||
170 | /** Writes a string as UTF-8. | ||
171 | Note: no length coding and no end byte are written, | ||
172 | just the pure string! | ||
173 | */ | ||
174 | public void write(String str) | ||
175 | { | ||
176 | write(str, false); | ||
177 | } | ||
178 | |||
179 | |||
180 | /** Writes a string as UTF-8, including a length coding. | ||
181 | In front of the string, the length in bytes is written | ||
182 | as a 32 bit integer. No end byte is written. | ||
183 | */ | ||
184 | public void writeWithLength(String str) | ||
185 | { | ||
186 | write(str, true); | ||
187 | } | ||
188 | |||
189 | |||
190 | /** Writes a string as UTF-8, with or without a length coding. | ||
191 | If a length coding is requested, the length in (UTF8-)bytes is written | ||
192 | as a 32 bit integer in front of the string. | ||
193 | No end byte is written. | ||
194 | */ | ||
195 | private void write(String str, boolean bWithLength) | ||
196 | { | ||
197 | byte[] aBytes = null; | ||
198 | try | ||
199 | { | ||
200 | aBytes = str.getBytes("UTF-8"); | ||
201 | } | ||
202 | catch (UnsupportedEncodingException e) | ||
203 | { | ||
204 | if (TDebug.TraceAllExceptions) TDebug.out(e); | ||
205 | } | ||
206 | if (bWithLength) | ||
207 | { | ||
208 | write(aBytes.length, 32); | ||
209 | } | ||
210 | for (int i = 0; i < aBytes.length; i++) | ||
211 | { | ||
212 | write(aBytes[i], 8); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | |||
217 | /** Reads a UTF-8 coded string with length coding. | ||
218 | It is expected that at the current read position, | ||
219 | there is a 32 bit integer containing the length in (UTF8-)bytes, | ||
220 | followed by the specified number of bytes in UTF-8 coding. | ||
221 | |||
222 | @return the string read from the buffer or null if an error occurs. | ||
223 | */ | ||
224 | public String readString() | ||
225 | { | ||
226 | int length = read(32); | ||
227 | if (length < 0) | ||
228 | { | ||
229 | return null; | ||
230 | } | ||
231 | return readString(length); | ||
232 | } | ||
233 | |||
234 | |||
235 | /** Reads a UTF-8 coded string without length coding. | ||
236 | It is expected that at the current read position, | ||
237 | there is string in UTF-8 coding. | ||
238 | |||
239 | @return the string read from the buffer or null if an error occurs. | ||
240 | */ | ||
241 | public String readString(int nLength) | ||
242 | { | ||
243 | byte[] aBytes = new byte[nLength]; | ||
244 | for (int i = 0; i < nLength; i++) | ||
245 | { | ||
246 | aBytes[i] = (byte) read(8); | ||
247 | } | ||
248 | String s = null; | ||
249 | try | ||
250 | { | ||
251 | s = new String(aBytes, "UTF-8"); | ||
252 | } | ||
253 | catch (UnsupportedEncodingException e) | ||
254 | { | ||
255 | if (TDebug.TraceAllExceptions) TDebug.out(e); | ||
256 | } | ||
257 | return s; | ||
258 | } | ||
259 | |||
260 | |||
261 | /** Reads a single bit. | ||
262 | */ | ||
263 | public boolean readFlag() | ||
264 | { | ||
265 | return (read(1) != 0); | ||
266 | } | ||
267 | |||
268 | private static native void setTrace(boolean bTrace); | ||
269 | |||
270 | // for debugging | ||
271 | public static void outBuffer(byte[] buffer) | ||
272 | { | ||
273 | String s = ""; | ||
274 | for (int i = 0; i < buffer.length; i++) | ||
275 | { | ||
276 | s += "" + buffer[i] + ", "; | ||
277 | } | ||
278 | TDebug.out("buffer: " + s); | ||
279 | } | ||
280 | } | ||
281 | |||
282 | |||
283 | |||
284 | /*** Buffer.java ***/ | ||
diff --git a/songdbj/org/tritonus/lowlevel/pogg/Ogg.java b/songdbj/org/tritonus/lowlevel/pogg/Ogg.java new file mode 100644 index 0000000000..086dd0f001 --- /dev/null +++ b/songdbj/org/tritonus/lowlevel/pogg/Ogg.java | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * Ogg.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 2000 - 2001 by Matthias Pfisterer | ||
9 | * | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU Library General Public License as published | ||
13 | * by the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU Library General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU Library General Public | ||
22 | * License along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | |<--- this code is formatted to fit into 80 columns --->| | ||
29 | */ | ||
30 | |||
31 | package org.tritonus.lowlevel.pogg; | ||
32 | |||
33 | import org.tritonus.share.TDebug; | ||
34 | |||
35 | |||
36 | /** libogg loading. | ||
37 | */ | ||
38 | public class Ogg | ||
39 | { | ||
40 | private static boolean sm_bIsLibraryAvailable = false; | ||
41 | |||
42 | |||
43 | |||
44 | static | ||
45 | { | ||
46 | Ogg.loadNativeLibrary(); | ||
47 | } | ||
48 | |||
49 | |||
50 | |||
51 | public static void loadNativeLibrary() | ||
52 | { | ||
53 | if (TDebug.TraceOggNative) { TDebug.out("Ogg.loadNativeLibrary(): begin"); } | ||
54 | |||
55 | if (! isLibraryAvailable()) | ||
56 | { | ||
57 | loadNativeLibraryImpl(); | ||
58 | } | ||
59 | if (TDebug.TraceOggNative) { TDebug.out("Ogg.loadNativeLibrary(): end"); } | ||
60 | } | ||
61 | |||
62 | |||
63 | |||
64 | /** Load the native library for ogg vorbis. | ||
65 | |||
66 | This method actually does the loading of the library. Unlike | ||
67 | {@link loadNativeLibrary() loadNativeLibrary()}, it does not | ||
68 | check if the library is already loaded. | ||
69 | |||
70 | */ | ||
71 | private static void loadNativeLibraryImpl() | ||
72 | { | ||
73 | if (TDebug.TraceOggNative) { TDebug.out("Ogg.loadNativeLibraryImpl(): loading native library tritonuspvorbis"); } | ||
74 | try | ||
75 | { | ||
76 | System.loadLibrary("tritonuspvorbis"); | ||
77 | // only reached if no exception occures | ||
78 | sm_bIsLibraryAvailable = true; | ||
79 | } | ||
80 | catch (Error e) | ||
81 | { | ||
82 | if (TDebug.TraceOggNative || | ||
83 | TDebug.TraceAllExceptions) | ||
84 | { | ||
85 | TDebug.out(e); | ||
86 | } | ||
87 | // throw e; | ||
88 | } | ||
89 | if (TDebug.TraceOggNative) { TDebug.out("Ogg.loadNativeLibraryImpl(): loaded"); } | ||
90 | } | ||
91 | |||
92 | |||
93 | |||
94 | /** Returns whether the libraries are installed correctly. | ||
95 | */ | ||
96 | public static boolean isLibraryAvailable() | ||
97 | { | ||
98 | return sm_bIsLibraryAvailable; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | |||
103 | |||
104 | /*** Ogg.java ***/ | ||
diff --git a/songdbj/org/tritonus/lowlevel/pogg/Packet.java b/songdbj/org/tritonus/lowlevel/pogg/Packet.java new file mode 100644 index 0000000000..15c5d9a66e --- /dev/null +++ b/songdbj/org/tritonus/lowlevel/pogg/Packet.java | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * Packet.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 2000 - 2001 by Matthias Pfisterer | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU Library General Public License as published | ||
12 | * by the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU Library General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU Library General Public | ||
21 | * License along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | |<--- this code is formatted to fit into 80 columns --->| | ||
27 | */ | ||
28 | |||
29 | package org.tritonus.lowlevel.pogg; | ||
30 | |||
31 | import org.tritonus.share.TDebug; | ||
32 | |||
33 | |||
34 | |||
35 | /** Wrapper for ogg_packet. | ||
36 | */ | ||
37 | public class Packet | ||
38 | { | ||
39 | static | ||
40 | { | ||
41 | Ogg.loadNativeLibrary(); | ||
42 | if (TDebug.TraceOggNative) | ||
43 | { | ||
44 | setTrace(true); | ||
45 | } | ||
46 | } | ||
47 | |||
48 | |||
49 | /** | ||
50 | * Holds the pointer to ogg_packet | ||
51 | * for the native code. | ||
52 | * This must be long to be 64bit-clean. | ||
53 | */ | ||
54 | private long m_lNativeHandle; | ||
55 | |||
56 | |||
57 | |||
58 | public Packet() | ||
59 | { | ||
60 | if (TDebug.TraceOggNative) { TDebug.out("Packet.<init>(): begin"); } | ||
61 | int nReturn = malloc(); | ||
62 | if (nReturn < 0) | ||
63 | { | ||
64 | throw new RuntimeException("malloc of ogg_packet failed"); | ||
65 | } | ||
66 | if (TDebug.TraceOggNative) { TDebug.out("Packet.<init>(): end"); } | ||
67 | } | ||
68 | |||
69 | |||
70 | |||
71 | public void finalize() | ||
72 | { | ||
73 | // TODO: call free() | ||
74 | // call super.finalize() first or last? | ||
75 | // and introduce a flag if free() has already been called? | ||
76 | } | ||
77 | |||
78 | |||
79 | |||
80 | private native int malloc(); | ||
81 | public native void free(); | ||
82 | |||
83 | |||
84 | |||
85 | /** Calls ogg_packet_clear(). | ||
86 | */ | ||
87 | public native void clear(); | ||
88 | |||
89 | |||
90 | |||
91 | /** Accesses packet and bytes. | ||
92 | */ | ||
93 | public native byte[] getData(); | ||
94 | |||
95 | |||
96 | /** Accesses b_o_s. | ||
97 | */ | ||
98 | public native boolean isBos(); | ||
99 | |||
100 | |||
101 | /** Accesses e_o_s. | ||
102 | */ | ||
103 | public native boolean isEos(); | ||
104 | |||
105 | |||
106 | public native long getGranulePos(); | ||
107 | |||
108 | |||
109 | public native long getPacketNo(); | ||
110 | |||
111 | |||
112 | /** Sets the data in the packet. | ||
113 | */ | ||
114 | public native void setData(byte[] abData, int nOffset, int nLength); | ||
115 | |||
116 | |||
117 | public native void setFlags(boolean bBos, boolean bEos, long lGranulePos, | ||
118 | long lPacketNo); | ||
119 | |||
120 | public void setFlags(boolean bBos, boolean bEos, long lGranulePos) | ||
121 | { | ||
122 | setFlags(bBos, bEos, lGranulePos, 0); | ||
123 | } | ||
124 | |||
125 | |||
126 | private static native void setTrace(boolean bTrace); | ||
127 | } | ||
128 | |||
129 | |||
130 | |||
131 | |||
132 | |||
133 | /*** Packet.java ***/ | ||
diff --git a/songdbj/org/tritonus/lowlevel/pogg/Page.java b/songdbj/org/tritonus/lowlevel/pogg/Page.java new file mode 100644 index 0000000000..3f89d7166e --- /dev/null +++ b/songdbj/org/tritonus/lowlevel/pogg/Page.java | |||
@@ -0,0 +1,298 @@ | |||
1 | /* | ||
2 | * Page.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 2000 - 2001 by Matthias Pfisterer | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU Library General Public License as published | ||
12 | * by the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU Library General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU Library General Public | ||
21 | * License along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | |<--- this code is formatted to fit into 80 columns --->| | ||
27 | */ | ||
28 | |||
29 | package org.tritonus.lowlevel.pogg; | ||
30 | |||
31 | import org.tritonus.share.TDebug; | ||
32 | |||
33 | |||
34 | |||
35 | /** Wrapper for ogg_page. | ||
36 | */ | ||
37 | public class Page | ||
38 | { | ||
39 | private static final int[] crc_lookup = | ||
40 | { | ||
41 | 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9, | ||
42 | 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005, | ||
43 | 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61, | ||
44 | 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd, | ||
45 | 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9, | ||
46 | 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75, | ||
47 | 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011, | ||
48 | 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd, | ||
49 | 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039, | ||
50 | 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5, | ||
51 | 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81, | ||
52 | 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d, | ||
53 | 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49, | ||
54 | 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95, | ||
55 | 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1, | ||
56 | 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d, | ||
57 | 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae, | ||
58 | 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072, | ||
59 | 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16, | ||
60 | 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca, | ||
61 | 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde, | ||
62 | 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02, | ||
63 | 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066, | ||
64 | 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba, | ||
65 | 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e, | ||
66 | 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692, | ||
67 | 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6, | ||
68 | 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a, | ||
69 | 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e, | ||
70 | 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2, | ||
71 | 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686, | ||
72 | 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a, | ||
73 | 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637, | ||
74 | 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb, | ||
75 | 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f, | ||
76 | 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53, | ||
77 | 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47, | ||
78 | 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b, | ||
79 | 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff, | ||
80 | 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623, | ||
81 | 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7, | ||
82 | 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b, | ||
83 | 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f, | ||
84 | 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3, | ||
85 | 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7, | ||
86 | 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b, | ||
87 | 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f, | ||
88 | 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3, | ||
89 | 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640, | ||
90 | 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c, | ||
91 | 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8, | ||
92 | 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24, | ||
93 | 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30, | ||
94 | 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec, | ||
95 | 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088, | ||
96 | 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654, | ||
97 | 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0, | ||
98 | 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c, | ||
99 | 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18, | ||
100 | 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4, | ||
101 | 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0, | ||
102 | 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c, | ||
103 | 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668, | ||
104 | 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4 | ||
105 | }; | ||
106 | |||
107 | |||
108 | private byte[] m_abHeader; | ||
109 | private int m_nHeaderLength; | ||
110 | private byte[] m_abBody; | ||
111 | private int m_nBodyLength; | ||
112 | |||
113 | |||
114 | public Page() | ||
115 | { | ||
116 | if (TDebug.TraceOggNative) { TDebug.out("Page.<init>(): begin"); } | ||
117 | if (TDebug.TraceOggNative) { TDebug.out("Page.<init>(): end"); } | ||
118 | } | ||
119 | |||
120 | |||
121 | |||
122 | private native int malloc(); | ||
123 | |||
124 | // TODO: remove calls to this method | ||
125 | public void free() | ||
126 | { | ||
127 | } | ||
128 | |||
129 | |||
130 | /** Calls ogg_page_version(). | ||
131 | */ | ||
132 | public int getVersion() | ||
133 | { | ||
134 | return m_abHeader[4] & 0xFF; | ||
135 | } | ||
136 | |||
137 | |||
138 | /** Calls ogg_page_continued(). | ||
139 | */ | ||
140 | public boolean isContinued() | ||
141 | { | ||
142 | return (m_abHeader[5] & 0x01) != 0; | ||
143 | } | ||
144 | |||
145 | |||
146 | |||
147 | /** Calls ogg_page_packets(). | ||
148 | */ | ||
149 | /* returns the number of packets that are completed on this page (if | ||
150 | the leading packet is begun on a previous page, but ends on this | ||
151 | page, it's counted */ | ||
152 | |||
153 | /* NOTE: | ||
154 | If a page consists of a packet begun on a previous page, and a new | ||
155 | packet begun (but not completed) on this page, the return will be: | ||
156 | ogg_page_packets(page) ==1, | ||
157 | ogg_page_continued(page) !=0 | ||
158 | |||
159 | If a page happens to be a single packet that was begun on a | ||
160 | previous page, and spans to the next page (in the case of a three or | ||
161 | more page packet), the return will be: | ||
162 | ogg_page_packets(page) ==0, | ||
163 | ogg_page_continued(page) !=0 | ||
164 | */ | ||
165 | public int getPackets() | ||
166 | { | ||
167 | int n = m_abHeader[26] & 0xFF; | ||
168 | int count = 0; | ||
169 | for (int i = 0; i < n; i++) | ||
170 | if ((m_abHeader[27 + i] & 0xFF) < 255) | ||
171 | count++; | ||
172 | return count; | ||
173 | } | ||
174 | |||
175 | |||
176 | |||
177 | /** Calls ogg_page_bos(). | ||
178 | */ | ||
179 | public boolean isBos() | ||
180 | { | ||
181 | return (m_abHeader[5] & 0x02) != 0; | ||
182 | } | ||
183 | |||
184 | |||
185 | |||
186 | /** Calls ogg_page_eos(). | ||
187 | */ | ||
188 | public boolean isEos() | ||
189 | { | ||
190 | return (m_abHeader[5] & 0x04) != 0; | ||
191 | } | ||
192 | |||
193 | |||
194 | |||
195 | /** Calls ogg_page_granulepos(). | ||
196 | */ | ||
197 | public long getGranulePos() | ||
198 | { | ||
199 | long granulepos = m_abHeader[13]&(0xff); | ||
200 | granulepos = (granulepos<<8)|(m_abHeader[12] & 0xFF); | ||
201 | granulepos = (granulepos<<8)|(m_abHeader[11] & 0xFF); | ||
202 | granulepos = (granulepos<<8)|(m_abHeader[10] & 0xFF); | ||
203 | granulepos = (granulepos<<8)|(m_abHeader[9] & 0xFF); | ||
204 | granulepos = (granulepos<<8)|(m_abHeader[8] & 0xFF); | ||
205 | granulepos = (granulepos<<8)|(m_abHeader[7] & 0xFF); | ||
206 | granulepos = (granulepos<<8)|(m_abHeader[6] & 0xFF); | ||
207 | return granulepos; | ||
208 | } | ||
209 | |||
210 | |||
211 | |||
212 | /** Calls ogg_page_serialno(). | ||
213 | */ | ||
214 | public int getSerialNo() | ||
215 | { | ||
216 | return m_abHeader[14] | | ||
217 | (m_abHeader[15] << 8) | | ||
218 | (m_abHeader[16] << 16) | | ||
219 | (m_abHeader[17] << 24); | ||
220 | } | ||
221 | |||
222 | |||
223 | |||
224 | /** Calls ogg_page_pageno(). | ||
225 | */ | ||
226 | public int getPageNo() | ||
227 | { | ||
228 | return m_abHeader[18] | | ||
229 | (m_abHeader[19] << 8) | | ||
230 | (m_abHeader[20] << 16) | | ||
231 | (m_abHeader[21] << 24); | ||
232 | } | ||
233 | |||
234 | |||
235 | |||
236 | /** Calls ogg_page_checksum_set(). | ||
237 | */ | ||
238 | public void setChecksum() | ||
239 | { | ||
240 | int crc_reg = 0; | ||
241 | |||
242 | /* safety; needed for API behavior, but not framing code */ | ||
243 | m_abHeader[22]=0; | ||
244 | m_abHeader[23]=0; | ||
245 | m_abHeader[24]=0; | ||
246 | m_abHeader[25]=0; | ||
247 | |||
248 | for(int i = 0; i < m_nHeaderLength; i++) | ||
249 | crc_reg = (crc_reg << 8) ^ crc_lookup[((crc_reg >>> 24) & 0xff) ^ (m_abHeader[i] & 0xFF)]; | ||
250 | for(int i = 0; i < m_nBodyLength; i++) | ||
251 | crc_reg = (crc_reg << 8) ^ crc_lookup[((crc_reg >>> 24) & 0xff) ^ (m_abBody[i] & 0xFF)]; | ||
252 | |||
253 | m_abHeader[22] = (byte) (crc_reg & 0xff); | ||
254 | m_abHeader[23] = (byte) ((crc_reg >> 8) & 0xff); | ||
255 | m_abHeader[24] = (byte) ((crc_reg >> 16) & 0xff); | ||
256 | m_abHeader[25] = (byte) ((crc_reg >> 24) & 0xff); | ||
257 | } | ||
258 | |||
259 | |||
260 | |||
261 | |||
262 | public byte[] getHeader() | ||
263 | { | ||
264 | byte[] abHeader = new byte[m_nHeaderLength]; | ||
265 | System.arraycopy(m_abHeader, 0, abHeader, 0, m_nHeaderLength); | ||
266 | return abHeader; | ||
267 | } | ||
268 | |||
269 | |||
270 | |||
271 | public byte[] getBody() | ||
272 | { | ||
273 | byte[] abBody = new byte[m_nBodyLength]; | ||
274 | System.arraycopy(m_abBody, 0, abBody, 0, m_nBodyLength); | ||
275 | return abBody; | ||
276 | } | ||
277 | |||
278 | |||
279 | |||
280 | public void setData(byte[] abHeader, int nHeaderOffset, | ||
281 | int nHeaderLength, | ||
282 | byte[] abBody, int nBodyOffset, | ||
283 | int nBodyLength) | ||
284 | { | ||
285 | m_abHeader = new byte[nHeaderLength]; | ||
286 | System.arraycopy(abHeader, nHeaderOffset, m_abHeader, 0, nHeaderLength); | ||
287 | m_nHeaderLength = nHeaderLength; | ||
288 | m_abBody = new byte[nBodyLength]; | ||
289 | System.arraycopy(abBody, nBodyOffset, m_abBody, 0, nBodyLength); | ||
290 | m_nBodyLength = nBodyLength; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | |||
295 | |||
296 | |||
297 | |||
298 | /*** Page.java ***/ | ||
diff --git a/songdbj/org/tritonus/lowlevel/pogg/StreamState.java b/songdbj/org/tritonus/lowlevel/pogg/StreamState.java new file mode 100644 index 0000000000..3fde33de8f --- /dev/null +++ b/songdbj/org/tritonus/lowlevel/pogg/StreamState.java | |||
@@ -0,0 +1,703 @@ | |||
1 | /* | ||
2 | * StreamState.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 2000 - 2005 by Matthias Pfisterer | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU Library General Public License as published | ||
12 | * by the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU Library General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU Library General Public | ||
21 | * License along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | |<--- this code is formatted to fit into 80 columns --->| | ||
27 | */ | ||
28 | |||
29 | package org.tritonus.lowlevel.pogg; | ||
30 | |||
31 | import org.tritonus.share.TDebug; | ||
32 | |||
33 | |||
34 | /** Wrapper for ogg_stream_state. | ||
35 | */ | ||
36 | public class StreamState | ||
37 | { | ||
38 | private static final int INITIAL_BODY_DATA_SIZE = 16 * 1024; | ||
39 | private static final int INITIAL_LACING_VALUES_SIZE = 1024; | ||
40 | |||
41 | /** The serial number of the stream. | ||
42 | This is set by init(). | ||
43 | */ | ||
44 | private int m_nSerialNo; | ||
45 | |||
46 | /** Storage for packet bodies. | ||
47 | */ | ||
48 | private byte[] m_abBodyData; | ||
49 | |||
50 | /** Number of bytes used in te body storage. | ||
51 | */ | ||
52 | private int m_nBodyFill; | ||
53 | |||
54 | /** Number of bytes aready returned (as pages) from the body storage. | ||
55 | */ | ||
56 | private int m_nBodyReturned; | ||
57 | |||
58 | /** Lacing values. Bit 0 to 7 contain the lacing value (mask | ||
59 | 0xFF). Bit 8 is set if the segment belongs to the first | ||
60 | packet of the stream (mask 0x100). Bit 9 is set ig the | ||
61 | segment belongs to the last packet of the stream (mask 0x200). | ||
62 | */ | ||
63 | private int[] m_anLacingValues; | ||
64 | |||
65 | /** Granule values. | ||
66 | */ | ||
67 | private long[] m_alGranuleValues; | ||
68 | |||
69 | /** Number of elements used in m_anLacingValues and m_alGranuleValues. | ||
70 | The elements with the index m_nLacingFill is the first free element. | ||
71 | */ | ||
72 | private int m_nLacingFill; | ||
73 | |||
74 | /** Pointer to the index in m_anLacingValues where the lacing values | ||
75 | of the last decoded packet start (??) | ||
76 | */ | ||
77 | private int m_nLacingPacket; | ||
78 | |||
79 | /** | ||
80 | */ | ||
81 | private int m_nLacingReturned; | ||
82 | |||
83 | private byte[] m_abHeader; | ||
84 | |||
85 | private int m_nHeaderFill; | ||
86 | |||
87 | private boolean m_bBos; | ||
88 | private boolean m_bEos; | ||
89 | private int m_nPageNo; | ||
90 | private long m_lPacketNo; | ||
91 | private long m_lGranulePos; | ||
92 | |||
93 | |||
94 | |||
95 | public StreamState() | ||
96 | { | ||
97 | if (TDebug.TraceOggNative) { TDebug.out("StreamState.<init>(): begin"); } | ||
98 | if (TDebug.TraceOggNative) { TDebug.out("StreamState.<init>(): end"); } | ||
99 | } | ||
100 | |||
101 | |||
102 | |||
103 | public void free() | ||
104 | { | ||
105 | } | ||
106 | |||
107 | |||
108 | |||
109 | /** Calls ogg_stream_init(). | ||
110 | */ | ||
111 | public int init(int nSerialNo) | ||
112 | { | ||
113 | m_nSerialNo = nSerialNo; | ||
114 | m_abBodyData = new byte[INITIAL_BODY_DATA_SIZE]; | ||
115 | m_nBodyFill = 0; | ||
116 | m_nBodyReturned = 0; | ||
117 | m_anLacingValues = new int[INITIAL_LACING_VALUES_SIZE]; | ||
118 | m_alGranuleValues = new long[INITIAL_LACING_VALUES_SIZE]; | ||
119 | m_nLacingFill = 0; | ||
120 | m_nLacingPacket = 0; | ||
121 | m_nLacingReturned = 0; | ||
122 | |||
123 | m_abHeader = new byte[282]; | ||
124 | m_nHeaderFill = 0; | ||
125 | |||
126 | m_bBos = false; | ||
127 | m_bEos = false; | ||
128 | m_nPageNo = 0; | ||
129 | m_lPacketNo = 0; | ||
130 | m_lGranulePos = 0; | ||
131 | |||
132 | // TODO: necessary? | ||
133 | for (int i = 0; i < m_abBodyData.length; i++) | ||
134 | m_abBodyData[i] = 0; | ||
135 | for (int i = 0; i < m_anLacingValues.length; i++) | ||
136 | m_anLacingValues[i] = 0; | ||
137 | for (int i = 0; i < m_alGranuleValues.length; i++) | ||
138 | m_alGranuleValues[i] = 0; | ||
139 | |||
140 | // TODO: remove return value | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | /** Calls ogg_stream_clear(). | ||
145 | */ | ||
146 | public int clear() | ||
147 | { | ||
148 | m_nSerialNo = 0; | ||
149 | m_abBodyData = null; | ||
150 | m_nBodyFill = 0; | ||
151 | m_nBodyReturned = 0; | ||
152 | m_anLacingValues = null; | ||
153 | m_alGranuleValues = null; | ||
154 | m_nLacingFill = 0; | ||
155 | m_nLacingPacket = 0; | ||
156 | m_nLacingReturned = 0; | ||
157 | |||
158 | m_abHeader = null; | ||
159 | m_nHeaderFill = 0; | ||
160 | |||
161 | m_bBos = false; | ||
162 | m_bEos = false; | ||
163 | m_nPageNo = 0; | ||
164 | m_lPacketNo = 0; | ||
165 | m_lGranulePos = 0; | ||
166 | |||
167 | // TODO: remove return value | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | /** Calls ogg_stream_reset(). | ||
172 | */ | ||
173 | public int reset() | ||
174 | { | ||
175 | m_nBodyFill = 0; | ||
176 | m_nBodyReturned = 0; | ||
177 | |||
178 | m_nLacingFill = 0; | ||
179 | m_nLacingPacket = 0; | ||
180 | m_nLacingReturned = 0; | ||
181 | |||
182 | m_nHeaderFill = 0; | ||
183 | |||
184 | m_bBos = false; | ||
185 | m_bEos = false; | ||
186 | m_nPageNo = -1; | ||
187 | m_lPacketNo = 0; | ||
188 | m_lGranulePos = 0; | ||
189 | |||
190 | // TODO: remove return value | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | /** Calls ogg_stream_eos(). | ||
195 | */ | ||
196 | public boolean isEOSReached() | ||
197 | { | ||
198 | return m_bEos; | ||
199 | } | ||
200 | |||
201 | /** Calls ogg_stream_packetin(). | ||
202 | */ | ||
203 | /* submit data to the internal buffer of the framing engine */ | ||
204 | public int packetIn(Packet packet) | ||
205 | { | ||
206 | int i; | ||
207 | byte[] abPacketData = packet.getData(); | ||
208 | int lacing_vals = abPacketData.length / 255 + 1; | ||
209 | |||
210 | if (m_nBodyReturned > 0) | ||
211 | { | ||
212 | /* advance packet data according to the body_returned pointer. We | ||
213 | had to keep it around to return a pointer into the buffer last | ||
214 | call */ | ||
215 | m_nBodyFill -= m_nBodyReturned; | ||
216 | if (m_nBodyFill > 0) | ||
217 | { | ||
218 | System.arraycopy(m_abBodyData, m_nBodyReturned, | ||
219 | m_abBodyData, 0, m_nBodyFill); | ||
220 | } | ||
221 | m_nBodyReturned = 0; | ||
222 | } | ||
223 | |||
224 | /* make sure we have the buffer storage */ | ||
225 | assureBodyDataCapacity(abPacketData.length); | ||
226 | assureLacingValuesCapacity(lacing_vals); | ||
227 | |||
228 | /* Copy in the submitted packet. Yes, the copy is a waste; | ||
229 | this is the liability of overly clean abstraction for the | ||
230 | time being. It will actually be fairly easy to eliminate | ||
231 | the extra copy in the future */ | ||
232 | System.arraycopy(abPacketData, 0, m_abBodyData, m_nBodyFill, | ||
233 | abPacketData.length); | ||
234 | m_nBodyFill += abPacketData.length; | ||
235 | |||
236 | /* Store lacing vals for this packet */ | ||
237 | for (i = 0; i < lacing_vals - 1; i++) | ||
238 | { | ||
239 | m_anLacingValues[m_nLacingFill + i] = 255; | ||
240 | m_alGranuleValues[m_nLacingFill + i] = m_lGranulePos; | ||
241 | } | ||
242 | m_anLacingValues[m_nLacingFill + i] = abPacketData.length % 255; | ||
243 | m_alGranuleValues[m_nLacingFill + i] = packet.getGranulePos(); | ||
244 | m_lGranulePos = packet.getGranulePos(); | ||
245 | |||
246 | /* flag the first segment as the beginning of the packet */ | ||
247 | m_anLacingValues[m_nLacingFill] |= 0x100; | ||
248 | |||
249 | m_nLacingFill += lacing_vals; | ||
250 | |||
251 | /* for the sake of completeness */ | ||
252 | m_lPacketNo++; | ||
253 | |||
254 | if (packet.isEos()) | ||
255 | m_bEos = true; | ||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | |||
260 | |||
261 | /** Calls ogg_stream_pageout(). | ||
262 | */ | ||
263 | /* This constructs pages from buffered packet segments. The pointers | ||
264 | returned are to static buffers; do not free. The returned buffers are | ||
265 | good only until the next call (using the same ogg_stream_state) */ | ||
266 | public int pageOut(Page page) | ||
267 | { | ||
268 | if ((m_bEos && m_nLacingFill > 0) || /* 'were done, now flush' */ | ||
269 | m_nBodyFill - m_nBodyReturned > 4096 || /* 'page nominal size' */ | ||
270 | m_nLacingFill >= 255 || /* 'segment table full' */ | ||
271 | (m_nLacingFill > 0 && ! m_bBos)) /* 'initial header page' */ | ||
272 | { | ||
273 | return flush(page); | ||
274 | } | ||
275 | /* not enough data to construct a page and not end of stream */ | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | |||
280 | |||
281 | /** Calls ogg_stream_flush(). | ||
282 | */ | ||
283 | /* This will flush remaining packets into a page (returning nonzero), | ||
284 | even if there is not enough data to trigger a flush normally | ||
285 | (undersized page). If there are no packets or partial packets to | ||
286 | flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will | ||
287 | try to flush a normal sized page like ogg_stream_pageout; a call to | ||
288 | ogg_stream_flush does not guarantee that all packets have flushed. | ||
289 | Only a return value of 0 from ogg_stream_flush indicates all packet | ||
290 | data is flushed into pages. | ||
291 | |||
292 | since ogg_stream_flush will flush the last page in a stream even if | ||
293 | it's undersized, you almost certainly want to use ogg_stream_pageout | ||
294 | (and *not* ogg_stream_flush) unless you specifically need to flush | ||
295 | an page regardless of size in the middle of a stream. | ||
296 | */ | ||
297 | public int flush(Page page) | ||
298 | { | ||
299 | int i; | ||
300 | int vals = 0; | ||
301 | int maxvals = Math.min(m_nLacingFill, 255); | ||
302 | int bytes = 0; | ||
303 | int acc = 0; | ||
304 | long granule_pos = m_alGranuleValues[0]; | ||
305 | |||
306 | if (maxvals == 0) | ||
307 | { | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | /* construct a page */ | ||
312 | /* decide how many segments to include */ | ||
313 | |||
314 | /* If this is the initial header case, the first page must | ||
315 | only include the initial header packet */ | ||
316 | if (! m_bBos) | ||
317 | { /* 'initial header page' case */ | ||
318 | granule_pos = 0; | ||
319 | for (vals = 0; vals < maxvals; vals++) | ||
320 | { | ||
321 | if ((m_anLacingValues[vals] & 0x0FF) < 255) | ||
322 | { | ||
323 | vals++; | ||
324 | break; | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | else | ||
329 | { | ||
330 | for (vals = 0; vals < maxvals; vals++) | ||
331 | { | ||
332 | if (acc > 4096) | ||
333 | break; | ||
334 | acc += (m_anLacingValues[vals] & 0x0FF); | ||
335 | granule_pos = m_alGranuleValues[vals]; | ||
336 | } | ||
337 | } | ||
338 | |||
339 | /* construct the header in temp storage */ | ||
340 | m_abHeader[0] = (byte) 'O'; | ||
341 | m_abHeader[1] = (byte) 'g'; | ||
342 | m_abHeader[2] = (byte) 'g'; | ||
343 | m_abHeader[3] = (byte) 'S'; | ||
344 | |||
345 | /* stream structure version */ | ||
346 | m_abHeader[4] = 0; | ||
347 | |||
348 | m_abHeader[5] = 0x00; | ||
349 | /* continued packet flag? */ | ||
350 | if ((m_anLacingValues[0] & 0x100) == 0) | ||
351 | m_abHeader[5] |= 0x01; | ||
352 | /* first page flag? */ | ||
353 | if (! m_bBos) | ||
354 | m_abHeader[5] |= 0x02; | ||
355 | /* last page flag? */ | ||
356 | if (m_bEos && m_nLacingFill == vals) | ||
357 | m_abHeader[5] |= 0x04; | ||
358 | m_bBos = true; | ||
359 | |||
360 | /* 64 bits of PCM position */ | ||
361 | for (i = 6; i < 14; i++) | ||
362 | { | ||
363 | m_abHeader[i] = (byte) (granule_pos & 0xFF); | ||
364 | granule_pos >>>= 8; | ||
365 | } | ||
366 | |||
367 | /* 32 bits of stream serial number */ | ||
368 | int serialno = m_nSerialNo; | ||
369 | for (i = 14; i < 18; i++) | ||
370 | { | ||
371 | m_abHeader[i] = (byte) (serialno & 0xFF); | ||
372 | serialno >>>= 8; | ||
373 | } | ||
374 | |||
375 | /* 32 bits of page counter (we have both counter and page header | ||
376 | because this val can roll over) */ | ||
377 | if (m_nPageNo == -1) | ||
378 | { | ||
379 | m_nPageNo = 0; /* because someone called | ||
380 | stream_reset; this would be a | ||
381 | strange thing to do in an | ||
382 | encode stream, but it has | ||
383 | plausible uses */ | ||
384 | } | ||
385 | int pageno = m_nPageNo++; | ||
386 | for (i = 18; i < 22; i++) | ||
387 | { | ||
388 | m_abHeader[i] = (byte) (pageno & 0xFF); | ||
389 | pageno >>>= 8; | ||
390 | } | ||
391 | |||
392 | /* zero for computation; filled in later */ | ||
393 | m_abHeader[22] = 0; | ||
394 | m_abHeader[23] = 0; | ||
395 | m_abHeader[24] = 0; | ||
396 | m_abHeader[25] = 0; | ||
397 | |||
398 | /* segment table */ | ||
399 | m_abHeader[26] = (byte) (vals & 0xFF); | ||
400 | for (i = 0; i < vals; i++) | ||
401 | { | ||
402 | m_abHeader[i + 27] = (byte) (m_anLacingValues[i] & 0xFF); | ||
403 | bytes += (m_anLacingValues[i] & 0xFF); | ||
404 | } | ||
405 | |||
406 | /* set pointers in the ogg_page struct */ | ||
407 | page.setData(m_abHeader, 0, vals + 27, | ||
408 | m_abBodyData, m_nBodyReturned, bytes); | ||
409 | m_nHeaderFill = vals + 27; | ||
410 | |||
411 | /* advance the lacing data and set the body_returned pointer */ | ||
412 | |||
413 | m_nLacingFill -= vals; | ||
414 | System.arraycopy(m_anLacingValues, vals, m_anLacingValues, 0, | ||
415 | m_nLacingFill); | ||
416 | System.arraycopy(m_alGranuleValues, vals, m_alGranuleValues, 0, | ||
417 | m_nLacingFill); | ||
418 | m_nBodyReturned += bytes; | ||
419 | |||
420 | /* calculate the checksum */ | ||
421 | |||
422 | page.setChecksum(); | ||
423 | |||
424 | /* done */ | ||
425 | return 1; | ||
426 | } | ||
427 | |||
428 | |||
429 | |||
430 | /** add the incoming page to the stream state; we decompose the | ||
431 | page into packet segments here as well. | ||
432 | |||
433 | @return 0 on success, -1 if the stream serial number stored in | ||
434 | the page does not match the one stored in the stream state or | ||
435 | if the protocol version stored in the page is greater than 0. | ||
436 | */ | ||
437 | public int pageIn(Page page) | ||
438 | { | ||
439 | byte[] header = page.getHeader(); | ||
440 | byte[] body = page.getBody(); | ||
441 | int nBodyOffset = 0; | ||
442 | int bodysize = body.length; | ||
443 | int segptr = 0; | ||
444 | |||
445 | int version = page.getVersion(); | ||
446 | boolean continued = page.isContinued(); | ||
447 | boolean bos = page.isBos(); | ||
448 | boolean eos = page.isEos(); | ||
449 | long granulepos = page.getGranulePos(); | ||
450 | int serialno = page.getSerialNo(); | ||
451 | int pageno = page.getPageNo(); | ||
452 | int segments = header[26] & 0xFF; | ||
453 | |||
454 | /* clean up 'returned data' */ | ||
455 | int lr = m_nLacingReturned; | ||
456 | int br = m_nBodyReturned; | ||
457 | |||
458 | /* body data */ | ||
459 | if (br > 0) | ||
460 | { | ||
461 | m_nBodyFill -= br; | ||
462 | if (m_nBodyFill > 0) | ||
463 | { | ||
464 | System.arraycopy(m_abBodyData, br, m_abBodyData, 0, | ||
465 | m_nBodyFill); | ||
466 | } | ||
467 | m_nBodyReturned = 0; | ||
468 | } | ||
469 | |||
470 | if (lr > 0) | ||
471 | { | ||
472 | /* segment table */ | ||
473 | if (m_nLacingFill - lr > 0) | ||
474 | { | ||
475 | System.arraycopy(m_anLacingValues, lr, m_anLacingValues, 0, | ||
476 | m_nLacingFill - lr); | ||
477 | System.arraycopy(m_alGranuleValues, lr, m_alGranuleValues, 0, | ||
478 | m_nLacingFill - lr); | ||
479 | } | ||
480 | m_nLacingFill -= lr; | ||
481 | m_nLacingPacket -= lr; | ||
482 | m_nLacingReturned = 0; | ||
483 | } | ||
484 | |||
485 | /* check the serial number */ | ||
486 | if (serialno != m_nSerialNo) | ||
487 | return -1; | ||
488 | if (version > 0) | ||
489 | return -1; | ||
490 | |||
491 | assureLacingValuesCapacity(segments + 1); | ||
492 | |||
493 | /* are we in sequence? */ | ||
494 | if (pageno != m_nPageNo) | ||
495 | { | ||
496 | int i; | ||
497 | |||
498 | /* unroll previous partial packet (if any) */ | ||
499 | for (i = m_nLacingPacket; i < m_nLacingFill; i++) | ||
500 | m_nBodyFill -= (m_anLacingValues[i] & 0xFF); | ||
501 | m_nLacingFill = m_nLacingPacket; | ||
502 | |||
503 | /* make a note of dropped data in segment table */ | ||
504 | if (m_nPageNo != -1) | ||
505 | { | ||
506 | m_anLacingValues[m_nLacingFill] = 0x400; | ||
507 | m_nLacingFill++; | ||
508 | m_nLacingPacket++; | ||
509 | } | ||
510 | |||
511 | /* are we a 'continued packet' page? If so, we'll need to skip | ||
512 | some segments */ | ||
513 | if (continued) | ||
514 | { | ||
515 | bos = false; | ||
516 | for (; segptr < segments; segptr++) | ||
517 | { | ||
518 | int val = header[27 + segptr] & 0xFF; | ||
519 | nBodyOffset += val; | ||
520 | bodysize -= val; | ||
521 | if (val < 255) | ||
522 | { | ||
523 | segptr++; | ||
524 | break; | ||
525 | } | ||
526 | } | ||
527 | } | ||
528 | } | ||
529 | |||
530 | if (bodysize > 0) | ||
531 | { | ||
532 | assureBodyDataCapacity(bodysize); | ||
533 | System.arraycopy(body, nBodyOffset, m_abBodyData, m_nBodyFill, | ||
534 | bodysize); | ||
535 | m_nBodyFill += bodysize; | ||
536 | } | ||
537 | |||
538 | int saved = -1; | ||
539 | while (segptr < segments) | ||
540 | { | ||
541 | int val = header[27 + segptr] & 0xFF; | ||
542 | m_anLacingValues[m_nLacingFill] = val; | ||
543 | m_alGranuleValues[m_nLacingFill] = -1; | ||
544 | |||
545 | if (bos) | ||
546 | { | ||
547 | m_anLacingValues[m_nLacingFill] |= 0x100; | ||
548 | bos = false; | ||
549 | } | ||
550 | |||
551 | if (val < 255) | ||
552 | saved = m_nLacingFill; | ||
553 | |||
554 | m_nLacingFill++; | ||
555 | segptr++; | ||
556 | |||
557 | if (val < 255) | ||
558 | m_nLacingPacket = m_nLacingFill; | ||
559 | } | ||
560 | |||
561 | /* set the granulepos on the last granuleval of the last full packet */ | ||
562 | if (saved != -1) | ||
563 | { | ||
564 | m_alGranuleValues[saved] = granulepos; | ||
565 | } | ||
566 | |||
567 | if (eos) | ||
568 | { | ||
569 | m_bEos = true; | ||
570 | if (m_nLacingFill > 0) | ||
571 | m_anLacingValues[m_nLacingFill - 1] |= 0x200; | ||
572 | } | ||
573 | |||
574 | m_nPageNo = pageno + 1; | ||
575 | |||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | |||
580 | /** Calls ogg_stream_packetout(). | ||
581 | */ | ||
582 | public int packetOut(Packet packet) | ||
583 | { | ||
584 | return packetOutInternal(packet, true); | ||
585 | } | ||
586 | |||
587 | |||
588 | /** Calls ogg_stream_packetpeek(). | ||
589 | */ | ||
590 | public int packetPeek(Packet packet) | ||
591 | { | ||
592 | return packetOutInternal(packet, false); | ||
593 | } | ||
594 | |||
595 | |||
596 | /** Retrieves a packet from the internal storage for emission. | ||
597 | This method is called by packetOut and packetPeek. | ||
598 | |||
599 | @param packet the Packet object to store the retrieved packet | ||
600 | data in. May be null if bAdvance is false. | ||
601 | |||
602 | @param bAdvance should the internal pointers to the packet | ||
603 | data storage be advanced to the next packet after retrieving | ||
604 | this one? Called with a value of true for ordinary packet out | ||
605 | and with a value of false for packet peek. | ||
606 | |||
607 | @return | ||
608 | */ | ||
609 | private int packetOutInternal(Packet packet, boolean bAdvance) | ||
610 | { | ||
611 | /* The last part of decode. We have the stream broken into | ||
612 | packet segments. Now we need to group them into packets | ||
613 | (or return the out of sync markers) */ | ||
614 | |||
615 | int ptr = m_nLacingReturned; | ||
616 | |||
617 | if (m_nLacingPacket <= ptr) | ||
618 | return 0; | ||
619 | |||
620 | if ((m_anLacingValues[ptr] & 0x400) != 0) | ||
621 | { | ||
622 | /* we need to tell the codec there's a gap; it might need | ||
623 | to handle previous packet dependencies. */ | ||
624 | m_nLacingReturned++; | ||
625 | m_lPacketNo++; | ||
626 | return -1; | ||
627 | } | ||
628 | |||
629 | if (packet == null && ! bAdvance) | ||
630 | return 1; /* just using peek as an inexpensive way | ||
631 | to ask if there's a whole packet | ||
632 | waiting */ | ||
633 | |||
634 | /* Gather the whole packet. We'll have no holes or a partial | ||
635 | * packet */ | ||
636 | int size = m_anLacingValues[ptr] & 0xFF; | ||
637 | int bytes = size; | ||
638 | /* last packet of the stream? */ | ||
639 | boolean eos = (m_anLacingValues[ptr] & 0x200) != 0; | ||
640 | /* first packet of the stream? */ | ||
641 | boolean bos = (m_anLacingValues[ptr] & 0x100) != 0; | ||
642 | |||
643 | while (size == 255) | ||
644 | { | ||
645 | int val = m_anLacingValues[++ptr]; | ||
646 | size = val & 0xff; | ||
647 | if ((val & 0x200) != 0) | ||
648 | eos = true; | ||
649 | bytes += size; | ||
650 | } | ||
651 | |||
652 | if (packet != null) | ||
653 | { | ||
654 | packet.setData(m_abBodyData, m_nBodyReturned, bytes); | ||
655 | packet.setFlags(bos, eos, m_alGranuleValues[ptr], m_lPacketNo); | ||
656 | } | ||
657 | |||
658 | if (bAdvance) | ||
659 | { | ||
660 | m_nBodyReturned += bytes; | ||
661 | m_nLacingReturned = ptr + 1; | ||
662 | m_lPacketNo++; | ||
663 | } | ||
664 | return 1; | ||
665 | } | ||
666 | |||
667 | |||
668 | private void assureBodyDataCapacity(int needed) | ||
669 | { | ||
670 | if (m_abBodyData.length <= m_nBodyFill + needed) | ||
671 | { | ||
672 | int nNewSize = m_abBodyData.length + needed + 1024; | ||
673 | byte[] abNewBodyData = new byte[nNewSize]; | ||
674 | System.arraycopy(m_abBodyData, 0, abNewBodyData, 0, | ||
675 | m_abBodyData.length); | ||
676 | m_abBodyData = abNewBodyData; | ||
677 | } | ||
678 | } | ||
679 | |||
680 | |||
681 | |||
682 | private void assureLacingValuesCapacity(int needed) | ||
683 | { | ||
684 | if (m_anLacingValues.length <= m_nLacingFill + needed) | ||
685 | { | ||
686 | int nNewSize = m_anLacingValues.length + needed + 32; | ||
687 | int[] anNewLacingValues = new int[nNewSize]; | ||
688 | System.arraycopy(m_anLacingValues, 0, anNewLacingValues, 0, | ||
689 | m_anLacingValues.length); | ||
690 | m_anLacingValues = anNewLacingValues; | ||
691 | long[] alNewGranuleValues = new long[nNewSize]; | ||
692 | System.arraycopy(m_alGranuleValues, 0, alNewGranuleValues, 0, | ||
693 | m_alGranuleValues.length); | ||
694 | m_alGranuleValues = alNewGranuleValues; | ||
695 | } | ||
696 | } | ||
697 | } | ||
698 | |||
699 | |||
700 | |||
701 | |||
702 | |||
703 | /*** StreamState.java ***/ | ||
diff --git a/songdbj/org/tritonus/lowlevel/pogg/SyncState.java b/songdbj/org/tritonus/lowlevel/pogg/SyncState.java new file mode 100644 index 0000000000..4246808bd3 --- /dev/null +++ b/songdbj/org/tritonus/lowlevel/pogg/SyncState.java | |||
@@ -0,0 +1,339 @@ | |||
1 | /* | ||
2 | * SyncState.java | ||
3 | * | ||
4 | * This file is part of Tritonus: http://www.tritonus.org/ | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * Copyright (c) 2000 - 2005 by Matthias Pfisterer | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU Library General Public License as published | ||
12 | * by the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU Library General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU Library General Public | ||
21 | * License along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | |<--- this code is formatted to fit into 80 columns --->| | ||
27 | */ | ||
28 | |||
29 | package org.tritonus.lowlevel.pogg; | ||
30 | |||
31 | import org.tritonus.share.TDebug; | ||
32 | |||
33 | |||
34 | /** Wrapper for ogg_sync_state. | ||
35 | */ | ||
36 | public class SyncState | ||
37 | { | ||
38 | /** The stream buffer. | ||
39 | This points to a buffer that holds the incoming data from a stream | ||
40 | until the data is emitted in form of a page. | ||
41 | */ | ||
42 | private byte[] m_abData; | ||
43 | |||
44 | /** The number of bytes in the stream buffer that are used. This | ||
45 | always counts from the beginning of the buffer. So | ||
46 | m_abData[m_nFill] is the first free byte in the buffer. | ||
47 | */ | ||
48 | private int m_nFill; | ||
49 | |||
50 | /** Number of bytes that have been used to construct a returned | ||
51 | page. This is counted from the beginning of the | ||
52 | buffer. m_abData[m_nReturned] is the first valid byte in the | ||
53 | buffer. | ||
54 | */ | ||
55 | private int m_nReturned; | ||
56 | |||
57 | /** | ||
58 | */ | ||
59 | private boolean m_bUnsynced; | ||
60 | |||
61 | /** | ||
62 | */ | ||
63 | private int m_nHeaderBytes; | ||
64 | |||
65 | /** | ||
66 | */ | ||
67 | private int m_nBodyBytes; | ||
68 | |||
69 | /** Page object for re-calculating the checksum. | ||
70 | */ | ||
71 | private Page m_tmpPage; | ||
72 | |||
73 | /** Storage for the checksum saved from the page. | ||
74 | */ | ||
75 | private byte[] m_abChecksum; | ||
76 | |||
77 | |||
78 | public SyncState() | ||
79 | { | ||
80 | if (TDebug.TraceOggNative) { TDebug.out("SyncState.<init>(): begin"); } | ||
81 | m_tmpPage = new Page(); | ||
82 | m_abChecksum = new byte[4]; | ||
83 | if (TDebug.TraceOggNative) { TDebug.out("SyncState.<init>(): end"); } | ||
84 | } | ||
85 | |||
86 | |||
87 | // TODO: remove calls to this method | ||
88 | public void free() | ||
89 | { | ||
90 | } | ||
91 | |||
92 | |||
93 | |||
94 | /** Calls ogg_sync_init(). | ||
95 | */ | ||
96 | public void init() | ||
97 | { | ||
98 | m_abData = null; | ||
99 | m_nFill = 0; | ||
100 | m_nReturned = 0; | ||
101 | m_bUnsynced = false; | ||
102 | m_nHeaderBytes = 0; | ||
103 | m_nBodyBytes = 0; | ||
104 | } | ||
105 | |||
106 | |||
107 | /** Calls ogg_sync_clear(). | ||
108 | */ | ||
109 | public void clear() | ||
110 | { | ||
111 | init(); | ||
112 | } | ||
113 | |||
114 | |||
115 | /** Calls ogg_sync_reset(). | ||
116 | */ | ||
117 | public void reset() | ||
118 | { | ||
119 | m_nFill = 0; | ||
120 | m_nReturned = 0; | ||
121 | m_bUnsynced = false; | ||
122 | m_nHeaderBytes = 0; | ||
123 | m_nBodyBytes = 0; | ||
124 | } | ||
125 | |||
126 | |||
127 | /** Writes to the stream buffer. | ||
128 | */ | ||
129 | public int write(byte[] abBuffer, int nBytes) | ||
130 | { | ||
131 | /* Clear out space that has been previously returned. */ | ||
132 | if (m_nReturned > 0) | ||
133 | { | ||
134 | m_nFill -= m_nReturned; | ||
135 | if (m_nFill > 0) | ||
136 | { | ||
137 | System.arraycopy(m_abData, m_nReturned, | ||
138 | m_abData, 0, | ||
139 | m_nFill); | ||
140 | } | ||
141 | m_nReturned = 0; | ||
142 | } | ||
143 | |||
144 | /* Check for enough space in the stream buffer and if it is | ||
145 | * allocated at all. If there isn't sufficient space, extend | ||
146 | * the buffer. */ | ||
147 | if (m_abData == null || nBytes > m_abData.length - m_nFill) | ||
148 | { | ||
149 | int nNewSize = nBytes + m_nFill + 4096; | ||
150 | byte[] abOldBuffer = m_abData; | ||
151 | m_abData = new byte[nNewSize]; | ||
152 | if (abOldBuffer != null) | ||
153 | { | ||
154 | System.arraycopy(abOldBuffer, 0, m_abData, 0, m_nFill); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | /* Now finally fill with the new data. */ | ||
159 | System.arraycopy(abBuffer, 0, m_abData, m_nFill, nBytes); | ||
160 | m_nFill += nBytes; | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | |||
165 | /** Synchronizes the stream. This method looks if there is a | ||
166 | complete, valid page in the stream buffer. If a page is found, | ||
167 | it is returned in the passed Page object. | ||
168 | |||
169 | @param page The Page to store the result of the page search | ||
170 | in. The content is only changed if the return value is > 0. | ||
171 | |||
172 | @return if a page has been found at the current location, the | ||
173 | length of the page in bytes is returned. If not enough data | ||
174 | for a page is available in the stream buffer, 0 is | ||
175 | returned. If data in the stream buffer has been skipped | ||
176 | because there is no page at the current position, the skip | ||
177 | amount in bytes is returned as a negative number. | ||
178 | */ | ||
179 | public int pageseek(Page page) | ||
180 | { | ||
181 | int nPage = m_nReturned; | ||
182 | int nBytes = m_nFill - m_nReturned; | ||
183 | |||
184 | if (m_nHeaderBytes == 0) | ||
185 | { | ||
186 | if (nBytes < 27) | ||
187 | { | ||
188 | /* Not enough data for a header. */ | ||
189 | return 0; | ||
190 | } | ||
191 | /* Verify capture pattern. */ | ||
192 | if (m_abData[nPage] != (byte) 'O' || | ||
193 | m_abData[nPage + 1] != (byte) 'g' || | ||
194 | m_abData[nPage + 2] != (byte) 'g' || | ||
195 | m_abData[nPage + 3] != (byte) 'S') | ||
196 | { | ||
197 | TDebug.out("wrong capture pattern"); | ||
198 | return syncFailure(); | ||
199 | } | ||
200 | int nHeaderBytes = (m_abData[nPage + 26] & 0xFF) + 27; | ||
201 | if (nBytes < nHeaderBytes) | ||
202 | { | ||
203 | /* Not enough data for header + segment table. */ | ||
204 | return 0; | ||
205 | } | ||
206 | /* Count up body length in the segment table. */ | ||
207 | for (int i = 0; i < (m_abData[nPage + 26] & 0xFF); i++) | ||
208 | { | ||
209 | m_nBodyBytes += (m_abData[nPage + 27 + i] & 0xFF); | ||
210 | } | ||
211 | m_nHeaderBytes = nHeaderBytes; | ||
212 | } | ||
213 | |||
214 | if (m_nBodyBytes + m_nHeaderBytes > nBytes) | ||
215 | { | ||
216 | /* Not enough data for the whole packet. */ | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | /* Save the original checksum, set it to zero and recalculate it. */ | ||
221 | System.arraycopy(m_abData, nPage + 22, m_abChecksum, 0, 4); | ||
222 | m_abData[nPage + 22] = 0; | ||
223 | m_abData[nPage + 23] = 0; | ||
224 | m_abData[nPage + 24] = 0; | ||
225 | m_abData[nPage + 25] = 0; | ||
226 | |||
227 | m_tmpPage.setData(m_abData, nPage, m_nHeaderBytes, | ||
228 | m_abData, nPage + m_nHeaderBytes, m_nBodyBytes); | ||
229 | // TDebug.out("temporary page:"); | ||
230 | // byte[] abHeader = m_tmpPage.getHeader(); | ||
231 | // TDebug.out("H0:" + m_abData[nPage + 0] + " - " + abHeader[0]); | ||
232 | // TDebug.out("H1:" + m_abData[nPage + 1] + " - " + abHeader[1]); | ||
233 | // TDebug.out("H2:" + m_abData[nPage + 2] + " - " + abHeader[2]); | ||
234 | // TDebug.out("H3:" + m_abData[nPage + 3] + " - " + abHeader[3]); | ||
235 | // TDebug.out("" + m_abChecksum[0] + " - " + abHeader[22]); | ||
236 | // TDebug.out("" + m_abChecksum[1] + " - " + abHeader[23]); | ||
237 | // TDebug.out("" + m_abChecksum[2] + " - " + abHeader[24]); | ||
238 | // TDebug.out("" + m_abChecksum[3] + " - " + abHeader[25]); | ||
239 | m_tmpPage.setChecksum(); | ||
240 | byte[] abHeader = m_tmpPage.getHeader(); | ||
241 | //m_tmpPage.free(); | ||
242 | if (abHeader[22] != m_abChecksum[0] || | ||
243 | abHeader[23] != m_abChecksum[1] || | ||
244 | abHeader[24] != m_abChecksum[2] || | ||
245 | abHeader[25] != m_abChecksum[3]) | ||
246 | { | ||
247 | TDebug.out("wrong checksum"); | ||
248 | TDebug.out("" + m_abChecksum[0] + " - " + abHeader[22]); | ||
249 | TDebug.out("" + m_abChecksum[1] + " - " + abHeader[23]); | ||
250 | TDebug.out("" + m_abChecksum[2] + " - " + abHeader[24]); | ||
251 | TDebug.out("" + m_abChecksum[3] + " - " + abHeader[25]); | ||
252 | /* Copy back the saved checksum. */ | ||
253 | System.arraycopy(m_abChecksum, 0, m_abData, nPage + 22, 4); | ||
254 | return syncFailure(); | ||
255 | } | ||
256 | |||
257 | /* Ok, we have a correct page to emit. */ | ||
258 | page.setData(m_abData, nPage, m_nHeaderBytes, | ||
259 | m_abData, nPage + m_nHeaderBytes, m_nBodyBytes); | ||
260 | m_bUnsynced = false; | ||
261 | nBytes = m_nHeaderBytes + m_nBodyBytes; | ||
262 | m_nReturned += nBytes; | ||
263 | m_nHeaderBytes = 0; | ||
264 | m_nBodyBytes = 0; | ||
265 | return nBytes; | ||
266 | } | ||
267 | |||
268 | |||
269 | /** Auxiliary method for pageseek(). | ||
270 | */ | ||
271 | private int syncFailure() | ||
272 | { | ||
273 | int nPage = m_nReturned; | ||
274 | int nBytes = m_nFill - m_nReturned; | ||
275 | m_nHeaderBytes = 0; | ||
276 | m_nBodyBytes = 0; | ||
277 | int nNext = -1; | ||
278 | for (int i = 0; i < nBytes - 1; i++) | ||
279 | { | ||
280 | if (m_abData[nPage + 1 + i] == (byte) 'O') | ||
281 | { | ||
282 | nNext = nPage + 1 + i; | ||
283 | break; | ||
284 | } | ||
285 | } | ||
286 | if (nNext == -1) | ||
287 | { | ||
288 | nNext = m_nFill; | ||
289 | } | ||
290 | m_nReturned = nNext; | ||
291 | return -(nNext - nPage); | ||
292 | } | ||
293 | |||
294 | |||
295 | |||
296 | |||
297 | /** Returns a page from the stream buffer, if possible. This | ||
298 | method searches the current data in the stream buffer for the | ||
299 | beginning of a page. If there is one, it is returned in the | ||
300 | passed Page object. A synchronization error is signaled by a | ||
301 | return value of -1. However, only the first synchronization | ||
302 | error is reported. Consecutive sync errors are suppressed. | ||
303 | |||
304 | @param page The Page to store the result of the page search | ||
305 | in. The content is only changed if the return value is 1. | ||
306 | |||
307 | @return 1 if a page has been found, 0 if there is not enough | ||
308 | data, -1 if a synchronization error occured. | ||
309 | */ | ||
310 | public int pageOut(Page page) | ||
311 | { | ||
312 | while (true) | ||
313 | { | ||
314 | int nReturn = pageseek(page); | ||
315 | if (nReturn > 0) | ||
316 | { | ||
317 | return 1; | ||
318 | } | ||
319 | else if (nReturn == 0) | ||
320 | { | ||
321 | return 0; | ||
322 | } | ||
323 | else // nReturn < 0 | ||
324 | { | ||
325 | if (! m_bUnsynced) | ||
326 | { | ||
327 | m_bUnsynced = true; | ||
328 | return -1; | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | |||
335 | |||
336 | |||
337 | |||
338 | |||
339 | /*** SyncState.java ***/ | ||
diff --git a/songdbj/org/tritonus/lowlevel/pogg/package.html b/songdbj/org/tritonus/lowlevel/pogg/package.html new file mode 100644 index 0000000000..57b0e50763 --- /dev/null +++ b/songdbj/org/tritonus/lowlevel/pogg/package.html | |||
@@ -0,0 +1,12 @@ | |||
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
2 | <html> | ||
3 | <head> | ||
4 | </head> | ||
5 | |||
6 | <body> | ||
7 | <p>Alternative pure java implementation of the ogg library. | ||
8 | The classes provided here .</p> | ||
9 | |||
10 | @see org.tritonus.sampled.convert.pvorbis | ||
11 | </body> | ||
12 | </html> | ||