diff options
Diffstat (limited to 'songdbj/javazoom/spi/vorbis/sampled/file')
5 files changed, 735 insertions, 0 deletions
diff --git a/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileFormat.java b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileFormat.java new file mode 100644 index 0000000000..28b7c92a2a --- /dev/null +++ b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileFormat.java | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * VorbisAudioFileFormat. | ||
3 | * | ||
4 | * JavaZOOM : vorbisspi@javazoom.net | ||
5 | * http://www.javazoom.net | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Library General Public License as published | ||
9 | * by the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Library General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Library General Public | ||
18 | * License along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | package javazoom.spi.vorbis.sampled.file; | ||
24 | |||
25 | import java.util.Map; | ||
26 | |||
27 | import javax.sound.sampled.AudioFormat; | ||
28 | |||
29 | import org.tritonus.share.sampled.file.TAudioFileFormat; | ||
30 | |||
31 | /** | ||
32 | * @author JavaZOOM | ||
33 | */ | ||
34 | public class VorbisAudioFileFormat extends TAudioFileFormat | ||
35 | { | ||
36 | /** | ||
37 | * Contructor. | ||
38 | * @param type | ||
39 | * @param audioFormat | ||
40 | * @param nLengthInFrames | ||
41 | * @param nLengthInBytes | ||
42 | */ | ||
43 | public VorbisAudioFileFormat(Type type, AudioFormat audioFormat, int nLengthInFrames, int nLengthInBytes, Map properties) | ||
44 | { | ||
45 | super(type, audioFormat, nLengthInFrames, nLengthInBytes, properties); | ||
46 | } | ||
47 | |||
48 | /** | ||
49 | * Ogg Vorbis audio file format parameters. | ||
50 | * Some parameters might be unavailable. So availability test is required before reading any parameter. | ||
51 | * | ||
52 | * <br>AudioFileFormat parameters. | ||
53 | * <ul> | ||
54 | * <li><b>duration</b> [Long], duration in microseconds. | ||
55 | * <li><b>title</b> [String], Title of the stream. | ||
56 | * <li><b>author</b> [String], Name of the artist of the stream. | ||
57 | * <li><b>album</b> [String], Name of the album of the stream. | ||
58 | * <li><b>date</b> [String], The date (year) of the recording or release of the stream. | ||
59 | * <li><b>copyright</b> [String], Copyright message of the stream. | ||
60 | * <li><b>comment</b> [String], Comment of the stream. | ||
61 | * </ul> | ||
62 | * <br>Ogg Vorbis parameters. | ||
63 | * <ul> | ||
64 | * <li><b>ogg.length.bytes</b> [Integer], length in bytes. | ||
65 | * <li><b>ogg.bitrate.min.bps</b> [Integer], minimum bitrate. | ||
66 | * <li><b>ogg.bitrate.nominal.bps</b> [Integer], nominal bitrate. | ||
67 | * <li><b>ogg.bitrate.max.bps</b> [Integer], maximum bitrate. | ||
68 | * <li><b>ogg.channels</b> [Integer], number of channels 1 : mono, 2 : stereo. | ||
69 | * <li><b>ogg.frequency.hz</b> [Integer], sampling rate in hz. | ||
70 | * <li><b>ogg.version</b> [Integer], version. | ||
71 | * <li><b>ogg.serial</b> [Integer], serial number. | ||
72 | * <li><b>ogg.comment.track</b> [String], track number. | ||
73 | * <li><b>ogg.comment.genre</b> [String], genre field. | ||
74 | * <li><b>ogg.comment.encodedby</b> [String], encoded by field. | ||
75 | * <li><b>ogg.comment.ext</b> [String], extended comments (indexed): | ||
76 | * <br>For instance : | ||
77 | * <br>ogg.comment.ext.1=Something | ||
78 | * <br>ogg.comment.ext.2=Another comment | ||
79 | * </ul> | ||
80 | */ | ||
81 | public Map properties() | ||
82 | { | ||
83 | return super.properties(); | ||
84 | } | ||
85 | } | ||
diff --git a/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileReader.java b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileReader.java new file mode 100644 index 0000000000..40bc9cadee --- /dev/null +++ b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFileReader.java | |||
@@ -0,0 +1,502 @@ | |||
1 | /* | ||
2 | * VorbisAudioFileReader. | ||
3 | * | ||
4 | * JavaZOOM : vorbisspi@javazoom.net | ||
5 | * http://www.javazoom.net | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Library General Public License as published | ||
9 | * by the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Library General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Library General Public | ||
18 | * License along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | package javazoom.spi.vorbis.sampled.file; | ||
24 | |||
25 | import java.io.BufferedInputStream; | ||
26 | import java.io.File; | ||
27 | import java.io.FileInputStream; | ||
28 | import java.io.IOException; | ||
29 | import java.io.InputStream; | ||
30 | import java.net.URL; | ||
31 | import java.util.HashMap; | ||
32 | import java.util.StringTokenizer; | ||
33 | |||
34 | import javax.sound.sampled.AudioFileFormat; | ||
35 | import javax.sound.sampled.AudioFormat; | ||
36 | import javax.sound.sampled.AudioInputStream; | ||
37 | import javax.sound.sampled.AudioSystem; | ||
38 | import javax.sound.sampled.UnsupportedAudioFileException; | ||
39 | |||
40 | import org.tritonus.share.TDebug; | ||
41 | import org.tritonus.share.sampled.file.TAudioFileReader; | ||
42 | |||
43 | import com.jcraft.jogg.Packet; | ||
44 | import com.jcraft.jogg.Page; | ||
45 | import com.jcraft.jogg.StreamState; | ||
46 | import com.jcraft.jogg.SyncState; | ||
47 | import com.jcraft.jorbis.Block; | ||
48 | import com.jcraft.jorbis.Comment; | ||
49 | import com.jcraft.jorbis.DspState; | ||
50 | import com.jcraft.jorbis.Info; | ||
51 | import com.jcraft.jorbis.JOrbisException; | ||
52 | import com.jcraft.jorbis.VorbisFile; | ||
53 | |||
54 | /** | ||
55 | * This class implements the AudioFileReader class and provides an | ||
56 | * Ogg Vorbis file reader for use with the Java Sound Service Provider Interface. | ||
57 | */ | ||
58 | public class VorbisAudioFileReader extends TAudioFileReader | ||
59 | { | ||
60 | private SyncState oggSyncState_ = null; | ||
61 | private StreamState oggStreamState_ = null; | ||
62 | private Page oggPage_ = null; | ||
63 | private Packet oggPacket_ = null; | ||
64 | private Info vorbisInfo = null; | ||
65 | private Comment vorbisComment = null; | ||
66 | private DspState vorbisDspState = null; | ||
67 | private Block vorbisBlock = null; | ||
68 | private int bufferMultiple_ = 4; | ||
69 | private int bufferSize_ = bufferMultiple_ * 256 * 2; | ||
70 | private int convsize = bufferSize_ * 2; | ||
71 | private byte[] convbuffer = new byte[convsize]; | ||
72 | private byte[] buffer = null; | ||
73 | private int bytes = 0; | ||
74 | private int rate = 0; | ||
75 | private int channels = 0; | ||
76 | |||
77 | private int index = 0; | ||
78 | private InputStream oggBitStream_ = null; | ||
79 | |||
80 | private static final int INITAL_READ_LENGTH = 64000; | ||
81 | private static final int MARK_LIMIT = INITAL_READ_LENGTH + 1; | ||
82 | |||
83 | public VorbisAudioFileReader() | ||
84 | { | ||
85 | super(MARK_LIMIT, true); | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * Return the AudioFileFormat from the given file. | ||
90 | */ | ||
91 | public AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException | ||
92 | { | ||
93 | if (TDebug.TraceAudioFileReader) TDebug.out("getAudioFileFormat(File file)"); | ||
94 | InputStream inputStream = null; | ||
95 | try | ||
96 | { | ||
97 | inputStream = new BufferedInputStream(new FileInputStream(file)); | ||
98 | inputStream.mark(MARK_LIMIT); | ||
99 | AudioFileFormat aff = getAudioFileFormat(inputStream); | ||
100 | inputStream.reset(); | ||
101 | // Get Vorbis file info such as length in seconds. | ||
102 | VorbisFile vf = new VorbisFile(file.getAbsolutePath()); | ||
103 | return getAudioFileFormat(inputStream,(int) file.length(), (int) Math.round((vf.time_total(-1))*1000)); | ||
104 | } | ||
105 | catch (JOrbisException e) | ||
106 | { | ||
107 | throw new IOException(e.getMessage()); | ||
108 | } | ||
109 | finally | ||
110 | { | ||
111 | if (inputStream != null) inputStream.close(); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | /** | ||
116 | * Return the AudioFileFormat from the given URL. | ||
117 | */ | ||
118 | public AudioFileFormat getAudioFileFormat(URL url) throws UnsupportedAudioFileException, IOException | ||
119 | { | ||
120 | if (TDebug.TraceAudioFileReader) TDebug.out("getAudioFileFormat(URL url)"); | ||
121 | InputStream inputStream = url.openStream(); | ||
122 | try | ||
123 | { | ||
124 | return getAudioFileFormat(inputStream); | ||
125 | } | ||
126 | finally | ||
127 | { | ||
128 | if (inputStream != null) inputStream.close(); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * Return the AudioFileFormat from the given InputStream. | ||
134 | */ | ||
135 | public AudioFileFormat getAudioFileFormat(InputStream inputStream) throws UnsupportedAudioFileException, IOException | ||
136 | { | ||
137 | if (TDebug.TraceAudioFileReader) TDebug.out("getAudioFileFormat(InputStream inputStream)"); | ||
138 | try | ||
139 | { | ||
140 | if (!inputStream.markSupported()) inputStream = new BufferedInputStream(inputStream); | ||
141 | inputStream.mark(MARK_LIMIT); | ||
142 | return getAudioFileFormat(inputStream, AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED); | ||
143 | } | ||
144 | finally | ||
145 | { | ||
146 | inputStream.reset(); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * Return the AudioFileFormat from the given InputStream and length in bytes. | ||
152 | */ | ||
153 | public AudioFileFormat getAudioFileFormat(InputStream inputStream, long medialength) throws UnsupportedAudioFileException, IOException | ||
154 | { | ||
155 | return getAudioFileFormat(inputStream, (int) medialength, AudioSystem.NOT_SPECIFIED); | ||
156 | } | ||
157 | |||
158 | |||
159 | /** | ||
160 | * Return the AudioFileFormat from the given InputStream, length in bytes and length in milliseconds. | ||
161 | */ | ||
162 | protected AudioFileFormat getAudioFileFormat(InputStream bitStream, int mediaLength, int totalms) throws UnsupportedAudioFileException, IOException | ||
163 | { | ||
164 | HashMap aff_properties = new HashMap(); | ||
165 | HashMap af_properties = new HashMap(); | ||
166 | if (totalms == AudioSystem.NOT_SPECIFIED) | ||
167 | { | ||
168 | totalms = 0; | ||
169 | } | ||
170 | if (totalms <= 0) | ||
171 | { | ||
172 | totalms = 0; | ||
173 | } | ||
174 | else | ||
175 | { | ||
176 | aff_properties.put("duration",new Long(totalms*1000)); | ||
177 | } | ||
178 | oggBitStream_ = bitStream; | ||
179 | init_jorbis(); | ||
180 | index = 0; | ||
181 | try | ||
182 | { | ||
183 | readHeaders(aff_properties, af_properties); | ||
184 | } | ||
185 | catch (IOException ioe) | ||
186 | { | ||
187 | if (TDebug.TraceAudioFileReader) | ||
188 | { | ||
189 | TDebug.out(ioe.getMessage()); | ||
190 | } | ||
191 | throw new UnsupportedAudioFileException(ioe.getMessage()); | ||
192 | } | ||
193 | |||
194 | String dmp = vorbisInfo.toString(); | ||
195 | if (TDebug.TraceAudioFileReader) | ||
196 | { | ||
197 | TDebug.out(dmp); | ||
198 | } | ||
199 | int ind = dmp.lastIndexOf("bitrate:"); | ||
200 | int minbitrate = -1; | ||
201 | int nominalbitrate = -1; | ||
202 | int maxbitrate = -1; | ||
203 | if (ind != -1) | ||
204 | { | ||
205 | dmp = dmp.substring(ind + 8, dmp.length()); | ||
206 | StringTokenizer st = new StringTokenizer(dmp, ","); | ||
207 | if (st.hasMoreTokens()) | ||
208 | { | ||
209 | minbitrate = Integer.parseInt(st.nextToken()); | ||
210 | } | ||
211 | if (st.hasMoreTokens()) | ||
212 | { | ||
213 | nominalbitrate = Integer.parseInt(st.nextToken()); | ||
214 | } | ||
215 | if (st.hasMoreTokens()) | ||
216 | { | ||
217 | maxbitrate = Integer.parseInt(st.nextToken()); | ||
218 | } | ||
219 | } | ||
220 | if (nominalbitrate > 0) af_properties.put("bitrate",new Integer(nominalbitrate)); | ||
221 | af_properties.put("vbr",new Boolean(true)); | ||
222 | |||
223 | if (minbitrate > 0) aff_properties.put("ogg.bitrate.min.bps",new Integer(minbitrate)); | ||
224 | if (maxbitrate > 0) aff_properties.put("ogg.bitrate.max.bps",new Integer(maxbitrate)); | ||
225 | if (nominalbitrate > 0) aff_properties.put("ogg.bitrate.nominal.bps",new Integer(nominalbitrate)); | ||
226 | if (vorbisInfo.channels > 0) aff_properties.put("ogg.channels",new Integer(vorbisInfo.channels)); | ||
227 | if (vorbisInfo.rate > 0) aff_properties.put("ogg.frequency.hz",new Integer(vorbisInfo.rate)); | ||
228 | if (mediaLength > 0) aff_properties.put("ogg.length.bytes",new Integer(mediaLength)); | ||
229 | aff_properties.put("ogg.version",new Integer(vorbisInfo.version)); | ||
230 | |||
231 | AudioFormat.Encoding encoding = VorbisEncoding.VORBISENC; | ||
232 | AudioFormat format = new VorbisAudioFormat(encoding, vorbisInfo.rate, AudioSystem.NOT_SPECIFIED, vorbisInfo.channels, AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED, true,af_properties); | ||
233 | AudioFileFormat.Type type = VorbisFileFormatType.OGG; | ||
234 | return new VorbisAudioFileFormat(VorbisFileFormatType.OGG, format, AudioSystem.NOT_SPECIFIED, mediaLength,aff_properties); | ||
235 | } | ||
236 | |||
237 | /** | ||
238 | * Return the AudioInputStream from the given InputStream. | ||
239 | */ | ||
240 | public AudioInputStream getAudioInputStream(InputStream inputStream) throws UnsupportedAudioFileException, IOException | ||
241 | { | ||
242 | if (TDebug.TraceAudioFileReader) TDebug.out("getAudioInputStream(InputStream inputStream)"); | ||
243 | return getAudioInputStream(inputStream, AudioSystem.NOT_SPECIFIED, AudioSystem.NOT_SPECIFIED); | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * Return the AudioInputStream from the given InputStream. | ||
248 | */ | ||
249 | public AudioInputStream getAudioInputStream(InputStream inputStream, int medialength, int totalms) throws UnsupportedAudioFileException, IOException | ||
250 | { | ||
251 | if (TDebug.TraceAudioFileReader) TDebug.out("getAudioInputStream(InputStream inputStreamint medialength, int totalms)"); | ||
252 | try | ||
253 | { | ||
254 | if (!inputStream.markSupported()) inputStream = new BufferedInputStream(inputStream); | ||
255 | inputStream.mark(MARK_LIMIT); | ||
256 | AudioFileFormat audioFileFormat = getAudioFileFormat(inputStream, medialength, totalms); | ||
257 | inputStream.reset(); | ||
258 | return new AudioInputStream(inputStream, audioFileFormat.getFormat(), audioFileFormat.getFrameLength()); | ||
259 | } | ||
260 | catch (UnsupportedAudioFileException e) | ||
261 | { | ||
262 | inputStream.reset(); | ||
263 | throw e; | ||
264 | } | ||
265 | catch (IOException e) | ||
266 | { | ||
267 | inputStream.reset(); | ||
268 | throw e; | ||
269 | } | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * Return the AudioInputStream from the given File. | ||
274 | */ | ||
275 | public AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException | ||
276 | { | ||
277 | if (TDebug.TraceAudioFileReader) TDebug.out("getAudioInputStream(File file)"); | ||
278 | InputStream inputStream = new FileInputStream(file); | ||
279 | try | ||
280 | { | ||
281 | return getAudioInputStream(inputStream); | ||
282 | } | ||
283 | catch (UnsupportedAudioFileException e) | ||
284 | { | ||
285 | if (inputStream != null) inputStream.close(); | ||
286 | throw e; | ||
287 | } | ||
288 | catch (IOException e) | ||
289 | { | ||
290 | if (inputStream != null) inputStream.close(); | ||
291 | throw e; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * Return the AudioInputStream from the given URL. | ||
297 | */ | ||
298 | public AudioInputStream getAudioInputStream(URL url) throws UnsupportedAudioFileException, IOException | ||
299 | { | ||
300 | if (TDebug.TraceAudioFileReader) TDebug.out("getAudioInputStream(URL url)"); | ||
301 | InputStream inputStream = url.openStream(); | ||
302 | try | ||
303 | { | ||
304 | return getAudioInputStream(inputStream); | ||
305 | } | ||
306 | catch (UnsupportedAudioFileException e) | ||
307 | { | ||
308 | if (inputStream != null) inputStream.close(); | ||
309 | throw e; | ||
310 | } | ||
311 | catch (IOException e) | ||
312 | { | ||
313 | if (inputStream != null) inputStream.close(); | ||
314 | throw e; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * Reads headers and comments. | ||
320 | */ | ||
321 | private void readHeaders(HashMap aff_properties, HashMap af_properties) throws IOException | ||
322 | { | ||
323 | if(TDebug.TraceAudioConverter) TDebug.out("readHeaders("); | ||
324 | index = oggSyncState_.buffer(bufferSize_); | ||
325 | buffer = oggSyncState_.data; | ||
326 | bytes = readFromStream(buffer, index, bufferSize_); | ||
327 | if(bytes == -1) | ||
328 | { | ||
329 | if(TDebug.TraceAudioConverter) TDebug.out("Cannot get any data from selected Ogg bitstream."); | ||
330 | throw new IOException("Cannot get any data from selected Ogg bitstream."); | ||
331 | } | ||
332 | oggSyncState_.wrote(bytes); | ||
333 | if(oggSyncState_.pageout(oggPage_) != 1) | ||
334 | { | ||
335 | if(bytes < bufferSize_) | ||
336 | { | ||
337 | throw new IOException("EOF"); | ||
338 | } | ||
339 | if(TDebug.TraceAudioConverter) TDebug.out("Input does not appear to be an Ogg bitstream."); | ||
340 | throw new IOException("Input does not appear to be an Ogg bitstream."); | ||
341 | } | ||
342 | oggStreamState_.init(oggPage_.serialno()); | ||
343 | vorbisInfo.init(); | ||
344 | vorbisComment.init(); | ||
345 | aff_properties.put("ogg.serial",new Integer(oggPage_.serialno())); | ||
346 | if(oggStreamState_.pagein(oggPage_) < 0) | ||
347 | { | ||
348 | // error; stream version mismatch perhaps | ||
349 | if(TDebug.TraceAudioConverter) TDebug.out("Error reading first page of Ogg bitstream data."); | ||
350 | throw new IOException("Error reading first page of Ogg bitstream data."); | ||
351 | } | ||
352 | if(oggStreamState_.packetout(oggPacket_) != 1) | ||
353 | { | ||
354 | // no page? must not be vorbis | ||
355 | if(TDebug.TraceAudioConverter) TDebug.out("Error reading initial header packet."); | ||
356 | throw new IOException("Error reading initial header packet."); | ||
357 | } | ||
358 | if(vorbisInfo.synthesis_headerin(vorbisComment, oggPacket_) < 0) | ||
359 | { | ||
360 | // error case; not a vorbis header | ||
361 | if(TDebug.TraceAudioConverter) TDebug.out("This Ogg bitstream does not contain Vorbis audio data."); | ||
362 | throw new IOException("This Ogg bitstream does not contain Vorbis audio data."); | ||
363 | } | ||
364 | int i = 0; | ||
365 | while(i < 2) | ||
366 | { | ||
367 | while(i < 2) | ||
368 | { | ||
369 | int result = oggSyncState_.pageout(oggPage_); | ||
370 | if(result == 0) | ||
371 | { | ||
372 | break; | ||
373 | } // Need more data | ||
374 | if(result == 1) | ||
375 | { | ||
376 | oggStreamState_.pagein(oggPage_); | ||
377 | while(i < 2) | ||
378 | { | ||
379 | result = oggStreamState_.packetout(oggPacket_); | ||
380 | if(result == 0) | ||
381 | { | ||
382 | break; | ||
383 | } | ||
384 | if(result == -1) | ||
385 | { | ||
386 | if(TDebug.TraceAudioConverter) TDebug.out("Corrupt secondary header. Exiting."); | ||
387 | throw new IOException("Corrupt secondary header. Exiting."); | ||
388 | } | ||
389 | vorbisInfo.synthesis_headerin(vorbisComment, oggPacket_); | ||
390 | i++; | ||
391 | } | ||
392 | } | ||
393 | } | ||
394 | index = oggSyncState_.buffer(bufferSize_); | ||
395 | buffer = oggSyncState_.data; | ||
396 | bytes = readFromStream(buffer, index, bufferSize_); | ||
397 | if(bytes == -1) | ||
398 | { | ||
399 | break; | ||
400 | } | ||
401 | if(bytes == 0 && i < 2) | ||
402 | { | ||
403 | if(TDebug.TraceAudioConverter) TDebug.out("End of file before finding all Vorbis headers!"); | ||
404 | throw new IOException("End of file before finding all Vorbis headers!"); | ||
405 | } | ||
406 | oggSyncState_.wrote(bytes); | ||
407 | } | ||
408 | // Read Ogg Vorbis comments. | ||
409 | byte[][] ptr = vorbisComment.user_comments; | ||
410 | String currComment = ""; | ||
411 | int c = 0; | ||
412 | for(int j = 0; j < ptr.length; j++) | ||
413 | { | ||
414 | if(ptr[j] == null) | ||
415 | { | ||
416 | break; | ||
417 | } | ||
418 | currComment = (new String(ptr[j], 0, ptr[j].length - 1)).trim(); | ||
419 | if(TDebug.TraceAudioConverter) TDebug.out(currComment); | ||
420 | if (currComment.toLowerCase().startsWith("artist")) | ||
421 | { | ||
422 | aff_properties.put("author",currComment.substring(7)); | ||
423 | } | ||
424 | else if (currComment.toLowerCase().startsWith("title")) | ||
425 | { | ||
426 | aff_properties.put("title",currComment.substring(6)); | ||
427 | } | ||
428 | else if (currComment.toLowerCase().startsWith("album")) | ||
429 | { | ||
430 | aff_properties.put("album",currComment.substring(6)); | ||
431 | } | ||
432 | else if (currComment.toLowerCase().startsWith("date")) | ||
433 | { | ||
434 | aff_properties.put("date",currComment.substring(5)); | ||
435 | } | ||
436 | else if (currComment.toLowerCase().startsWith("copyright")) | ||
437 | { | ||
438 | aff_properties.put("copyright",currComment.substring(10)); | ||
439 | } | ||
440 | else if (currComment.toLowerCase().startsWith("comment")) | ||
441 | { | ||
442 | aff_properties.put("comment",currComment.substring(8)); | ||
443 | } | ||
444 | else if (currComment.toLowerCase().startsWith("genre")) | ||
445 | { | ||
446 | aff_properties.put("ogg.comment.genre",currComment.substring(6)); | ||
447 | } | ||
448 | else if (currComment.toLowerCase().startsWith("tracknumber")) | ||
449 | { | ||
450 | aff_properties.put("ogg.comment.track",currComment.substring(12)); | ||
451 | } | ||
452 | else | ||
453 | { | ||
454 | c++; | ||
455 | aff_properties.put("ogg.comment.ext."+c,currComment); | ||
456 | } | ||
457 | aff_properties.put("ogg.comment.encodedby",new String(vorbisComment.vendor, 0, vorbisComment.vendor.length - 1)); | ||
458 | } | ||
459 | } | ||
460 | |||
461 | /** | ||
462 | * Reads from the oggBitStream_ a specified number of Bytes(bufferSize_) worth | ||
463 | * starting at index and puts them in the specified buffer[]. | ||
464 | * | ||
465 | * @return the number of bytes read or -1 if error. | ||
466 | */ | ||
467 | private int readFromStream(byte[] buffer, int index, int bufferSize_) | ||
468 | { | ||
469 | int bytes = 0; | ||
470 | try | ||
471 | { | ||
472 | bytes = oggBitStream_.read(buffer, index, bufferSize_); | ||
473 | } | ||
474 | catch (Exception e) | ||
475 | { | ||
476 | if (TDebug.TraceAudioFileReader) | ||
477 | { | ||
478 | TDebug.out("Cannot Read Selected Song"); | ||
479 | } | ||
480 | bytes = -1; | ||
481 | } | ||
482 | return bytes; | ||
483 | } | ||
484 | |||
485 | /** | ||
486 | * Initializes all the jOrbis and jOgg vars that are used for song playback. | ||
487 | */ | ||
488 | private void init_jorbis() | ||
489 | { | ||
490 | oggSyncState_ = new SyncState(); | ||
491 | oggStreamState_ = new StreamState(); | ||
492 | oggPage_ = new Page(); | ||
493 | oggPacket_ = new Packet(); | ||
494 | vorbisInfo = new Info(); | ||
495 | vorbisComment = new Comment(); | ||
496 | vorbisDspState = new DspState(); | ||
497 | vorbisBlock = new Block(vorbisDspState); | ||
498 | buffer = null; | ||
499 | bytes = 0; | ||
500 | oggSyncState_.init(); | ||
501 | } | ||
502 | } | ||
diff --git a/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFormat.java b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFormat.java new file mode 100644 index 0000000000..829ab2f8cd --- /dev/null +++ b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisAudioFormat.java | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * VorbisAudioFormat. | ||
3 | * | ||
4 | * JavaZOOM : vorbisspi@javazoom.net | ||
5 | * http://www.javazoom.net | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Library General Public License as published | ||
9 | * by the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Library General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Library General Public | ||
18 | * License along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | package javazoom.spi.vorbis.sampled.file; | ||
24 | |||
25 | import java.util.Map; | ||
26 | |||
27 | import javax.sound.sampled.AudioFormat; | ||
28 | |||
29 | import org.tritonus.share.sampled.TAudioFormat; | ||
30 | |||
31 | /** | ||
32 | * @author JavaZOOM | ||
33 | */ | ||
34 | public class VorbisAudioFormat extends TAudioFormat | ||
35 | { | ||
36 | /** | ||
37 | * Constructor. | ||
38 | * @param encoding | ||
39 | * @param nFrequency | ||
40 | * @param SampleSizeInBits | ||
41 | * @param nChannels | ||
42 | * @param FrameSize | ||
43 | * @param FrameRate | ||
44 | * @param isBigEndian | ||
45 | * @param properties | ||
46 | */ | ||
47 | public VorbisAudioFormat(AudioFormat.Encoding encoding, float nFrequency, int SampleSizeInBits, int nChannels, int FrameSize, float FrameRate, boolean isBigEndian, Map properties) | ||
48 | { | ||
49 | super(encoding, nFrequency, SampleSizeInBits, nChannels, FrameSize, FrameRate, isBigEndian, properties); | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * Ogg Vorbis audio format parameters. | ||
54 | * Some parameters might be unavailable. So availability test is required before reading any parameter. | ||
55 | * | ||
56 | * <br>AudioFormat parameters. | ||
57 | * <ul> | ||
58 | * <li><b>bitrate</b> [Integer], bitrate in bits per seconds, average bitrate for VBR enabled stream. | ||
59 | * <li><b>vbr</b> [Boolean], VBR flag. | ||
60 | * </ul> | ||
61 | */ | ||
62 | public Map properties() | ||
63 | { | ||
64 | return super.properties(); | ||
65 | } | ||
66 | } | ||
diff --git a/songdbj/javazoom/spi/vorbis/sampled/file/VorbisEncoding.java b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisEncoding.java new file mode 100644 index 0000000000..7800f1556d --- /dev/null +++ b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisEncoding.java | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * VorbisEncoding. | ||
3 | * | ||
4 | * JavaZOOM : vorbisspi@javazoom.net | ||
5 | * http://www.javazoom.net | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Library General Public License as published | ||
9 | * by the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Library General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Library General Public | ||
18 | * License along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | package javazoom.spi.vorbis.sampled.file; | ||
24 | |||
25 | import javax.sound.sampled.AudioFormat; | ||
26 | |||
27 | /** | ||
28 | * Encodings used by the VORBIS audio decoder. | ||
29 | */ | ||
30 | public class VorbisEncoding extends AudioFormat.Encoding | ||
31 | { | ||
32 | public static final AudioFormat.Encoding VORBISENC = new VorbisEncoding("VORBISENC"); | ||
33 | |||
34 | /** | ||
35 | * Constructors. | ||
36 | */ | ||
37 | public VorbisEncoding(String name) | ||
38 | { | ||
39 | super(name); | ||
40 | } | ||
41 | } | ||
diff --git a/songdbj/javazoom/spi/vorbis/sampled/file/VorbisFileFormatType.java b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisFileFormatType.java new file mode 100644 index 0000000000..f006bbfe1d --- /dev/null +++ b/songdbj/javazoom/spi/vorbis/sampled/file/VorbisFileFormatType.java | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * VorbisFileFormatType. | ||
3 | * | ||
4 | * JavaZOOM : vorbisspi@javazoom.net | ||
5 | * http://www.javazoom.net | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Library General Public License as published | ||
9 | * by the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Library General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Library General Public | ||
18 | * License along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | package javazoom.spi.vorbis.sampled.file; | ||
24 | |||
25 | import javax.sound.sampled.AudioFileFormat; | ||
26 | |||
27 | /** | ||
28 | * FileFormatTypes used by the VORBIS audio decoder. | ||
29 | */ | ||
30 | public class VorbisFileFormatType extends AudioFileFormat.Type | ||
31 | { | ||
32 | public static final AudioFileFormat.Type VORBIS = new VorbisFileFormatType("VORBIS", "ogg"); | ||
33 | public static final AudioFileFormat.Type OGG = new VorbisFileFormatType("OGG", "ogg"); | ||
34 | /** | ||
35 | * Constructor. | ||
36 | */ | ||
37 | public VorbisFileFormatType(String name, String extension) | ||
38 | { | ||
39 | super(name, extension); | ||
40 | } | ||
41 | } | ||