--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/AuFileReader.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,398 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.media.sound;
+
+import java.util.Vector;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.EOFException;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.SequenceInputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+
+/**
+ * AU file reader.
+ *
+ * @author Kara Kytle
+ * @author Jan Borgersen
+ * @author Florian Bomers
+ */
+public class AuFileReader extends SunFileReader {
+
+ /**
+ * AU reader type
+ */
+
+ public static final AudioFileFormat.Type types[] = {
+ AudioFileFormat.Type.AU
+ };
+
+
+ /**
+ * Constructs a new AuFileReader object.
+ */
+ public AuFileReader() {
+ }
+
+
+ // METHODS TO IMPLEMENT AudioFileReader
+
+ /**
+ * Obtains the audio file format of the input stream provided. The stream must
+ * point to valid audio file data. In general, audio file providers may
+ * need to read some data from the stream before determining whether they
+ * support it. These parsers must
+ * be able to mark the stream, read enough data to determine whether they
+ * support the stream, and, if not, reset the stream's read pointer to its original
+ * position. If the input stream does not support this, this method may fail
+ * with an IOException.
+ * @param stream the input stream from which file format information should be
+ * extracted
+ * @return an <code>AudioFileFormat</code> object describing the audio file format
+ * @throws UnsupportedAudioFileException if the stream does not point to valid audio
+ * file data recognized by the system
+ * @throws IOException if an I/O exception occurs
+ * @see InputStream#markSupported
+ * @see InputStream#mark
+ */
+ public AudioFileFormat getAudioFileFormat(InputStream stream) throws UnsupportedAudioFileException, IOException {
+
+ AudioFormat format = null;
+ AuFileFormat fileFormat = null;
+ int maxReadLength = 28;
+ boolean bigendian = false;
+ int magic = -1;
+ int headerSize = -1;
+ int dataSize = -1;
+ int encoding_local = -1;
+ int sampleRate = -1;
+ int frameRate = -1;
+ int frameSize = -1;
+ int channels = -1;
+ int sampleSizeInBits = 0;
+ int length = 0;
+ int nread = 0;
+ AudioFormat.Encoding encoding = null;
+
+ DataInputStream dis = new DataInputStream( stream );
+
+ dis.mark(maxReadLength);
+
+ magic = dis.readInt();
+
+ if (! (magic == AuFileFormat.AU_SUN_MAGIC) || (magic == AuFileFormat.AU_DEC_MAGIC) ||
+ (magic == AuFileFormat.AU_SUN_INV_MAGIC) || (magic == AuFileFormat.AU_DEC_INV_MAGIC) ) {
+
+ // not AU, reset the stream, place into exception, throw exception
+ dis.reset();
+ throw new UnsupportedAudioFileException("not an AU file");
+ }
+
+ if ((magic == AuFileFormat.AU_SUN_MAGIC) || (magic == AuFileFormat.AU_DEC_MAGIC)) {
+ bigendian = true; // otherwise little-endian
+ }
+
+ headerSize = (bigendian==true ? dis.readInt() : rllong(dis) ); nread += 4;
+ dataSize = (bigendian==true ? dis.readInt() : rllong(dis) ); nread += 4;
+ encoding_local = (bigendian==true ? dis.readInt() : rllong(dis) ); nread += 4;
+ sampleRate = (bigendian==true ? dis.readInt() : rllong(dis) ); nread += 4;
+ channels = (bigendian==true ? dis.readInt() : rllong(dis) ); nread += 4;
+
+ frameRate = sampleRate;
+
+ switch (encoding_local) {
+ case AuFileFormat.AU_ULAW_8:
+ encoding = AudioFormat.Encoding.ULAW;
+ sampleSizeInBits = 8;
+ break;
+ case AuFileFormat.AU_ALAW_8:
+ encoding = AudioFormat.Encoding.ALAW;
+ sampleSizeInBits = 8;
+ break;
+ case AuFileFormat.AU_LINEAR_8:
+ // $$jb: 04.29.99: 8bit linear is *signed*, not *unsigned*
+ encoding = AudioFormat.Encoding.PCM_SIGNED;
+ sampleSizeInBits = 8;
+ break;
+ case AuFileFormat.AU_LINEAR_16:
+ encoding = AudioFormat.Encoding.PCM_SIGNED;
+ sampleSizeInBits = 16;
+ break;
+ case AuFileFormat.AU_LINEAR_24:
+ encoding = AudioFormat.Encoding.PCM_SIGNED;
+
+ sampleSizeInBits = 24;
+ break;
+ case AuFileFormat.AU_LINEAR_32:
+ encoding = AudioFormat.Encoding.PCM_SIGNED;
+
+ sampleSizeInBits = 32;
+ break;
+ // $jb: 03.19.99: we don't support these ...
+ /* case AuFileFormat.AU_FLOAT:
+ encoding = new AudioFormat.FLOAT;
+ sampleSizeInBits = 32;
+ break;
+ case AuFileFormat.AU_DOUBLE:
+ encoding = new AudioFormat.DOUBLE;
+ sampleSizeInBits = 8;
+ break;
+ case AuFileFormat.AU_ADPCM_G721:
+ encoding = new AudioFormat.G721_ADPCM;
+ sampleSizeInBits = 16;
+ break;
+ case AuFileFormat.AU_ADPCM_G723_3:
+ encoding = new AudioFormat.G723_3;
+ sampleSize = 24;
+ SamplePerUnit = 8;
+ break;
+ case AuFileFormat.AU_ADPCM_G723_5:
+ encoding = new AudioFormat.G723_5;
+ sampleSize = 40;
+ SamplePerUnit = 8;
+ break;
+ */
+ default:
+ // unsupported filetype, throw exception
+ dis.reset();
+ throw new UnsupportedAudioFileException("not a valid AU file");
+ }
+
+ frameSize = calculatePCMFrameSize(sampleSizeInBits, channels);
+ //$$fb 2002-11-02: fix for 4629669: AU file reader: problems with empty files
+ if( dataSize < 0 ) {
+ length = AudioSystem.NOT_SPECIFIED;
+ } else {
+ //$$fb 2003-10-20: fix for 4940459: AudioInputStream.getFrameLength() returns 0 instead of NOT_SPECIFIED
+ length = dataSize / frameSize;
+ }
+
+ format = new AudioFormat( encoding, (float)sampleRate, sampleSizeInBits,
+ channels, frameSize, (float)frameRate, bigendian);
+
+ fileFormat = new AuFileFormat( AudioFileFormat.Type.AU, dataSize+headerSize,
+ format, length);
+
+ dis.reset(); // Throws IOException
+ return fileFormat;
+
+ }
+
+
+ /**
+ * Obtains the audio file format of the URL provided. The URL must
+ * point to valid audio file data.
+ * @param url the URL from which file format information should be
+ * extracted
+ * @return an <code>AudioFileFormat</code> object describing the audio file format
+ * @throws UnsupportedAudioFileException if the URL does not point to valid audio
+ * file data recognized by the system
+ * @throws IOException if an I/O exception occurs
+ */
+ public AudioFileFormat getAudioFileFormat(URL url) throws UnsupportedAudioFileException, IOException {
+
+ InputStream urlStream = null;
+ BufferedInputStream bis = null;
+ AudioFileFormat fileFormat = null;
+ AudioFormat format = null;
+
+ urlStream = url.openStream(); // throws IOException
+
+ try {
+ bis = new BufferedInputStream( urlStream, bisBufferSize );
+
+ fileFormat = getAudioFileFormat( bis ); // throws UnsupportedAudioFileException
+ } finally {
+ urlStream.close();
+ }
+
+ return fileFormat;
+ }
+
+
+ /**
+ * Obtains the audio file format of the File provided. The File must
+ * point to valid audio file data.
+ * @param file the File from which file format information should be
+ * extracted
+ * @return an <code>AudioFileFormat</code> object describing the audio file format
+ * @throws UnsupportedAudioFileException if the File does not point to valid audio
+ * file data recognized by the system
+ * @throws IOException if an I/O exception occurs
+ */
+ public AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException {
+
+ FileInputStream fis = null;
+ BufferedInputStream bis = null;
+ AudioFileFormat fileFormat = null;
+ AudioFormat format = null;
+
+ fis = new FileInputStream( file ); // throws IOException
+ // part of fix for 4325421
+ try {
+ bis = new BufferedInputStream( fis, bisBufferSize );
+ fileFormat = getAudioFileFormat( bis ); // throws UnsupportedAudioFileException
+ } finally {
+ fis.close();
+ }
+
+ return fileFormat;
+ }
+
+
+ /**
+ * Obtains an audio stream from the input stream provided. The stream must
+ * point to valid audio file data. In general, audio file providers may
+ * need to read some data from the stream before determining whether they
+ * support it. These parsers must
+ * be able to mark the stream, read enough data to determine whether they
+ * support the stream, and, if not, reset the stream's read pointer to its original
+ * position. If the input stream does not support this, this method may fail
+ * with an IOException.
+ * @param stream the input stream from which the <code>AudioInputStream</code> should be
+ * constructed
+ * @return an <code>AudioInputStream</code> object based on the audio file data contained
+ * in the input stream.
+ * @throws UnsupportedAudioFileException if the stream does not point to valid audio
+ * file data recognized by the system
+ * @throws IOException if an I/O exception occurs
+ * @see InputStream#markSupported
+ * @see InputStream#mark
+ */
+ public AudioInputStream getAudioInputStream(InputStream stream) throws UnsupportedAudioFileException, IOException {
+
+ DataInputStream dis = null;
+ int headerSize;
+ AudioFileFormat fileFormat = null;
+ AudioFormat format = null;
+
+
+ fileFormat = getAudioFileFormat( stream ); // throws UnsupportedAudioFileException, IOException
+
+ // if we passed this call, we have an AU file.
+
+ format = fileFormat.getFormat();
+
+ dis = new DataInputStream(stream);
+
+ // now seek past the header
+
+ dis.readInt(); // magic
+ headerSize = (format.isBigEndian()==true ? dis.readInt() : rllong(dis) );
+ dis.skipBytes( headerSize - 8 );
+
+
+ // we've got everything, and the stream should be at the
+ // beginning of the data chunk, so return an AudioInputStream.
+
+ return new AudioInputStream(dis, format, fileFormat.getFrameLength());
+ }
+
+
+ /**
+ * Obtains an audio stream from the URL provided. The URL must
+ * point to valid audio file data.
+ * @param url the URL for which the <code>AudioInputStream</code> should be
+ * constructed
+ * @return an <code>AudioInputStream</code> object based on the audio file data pointed
+ * to by the URL
+ * @throws UnsupportedAudioFileException if the URL does not point to valid audio
+ * file data recognized by the system
+ * @throws IOException if an I/O exception occurs
+ */
+ public AudioInputStream getAudioInputStream(URL url) throws UnsupportedAudioFileException, IOException {
+
+ InputStream urlStream = null;
+ BufferedInputStream bis = null;
+ AudioFileFormat fileFormat = null;
+
+ urlStream = url.openStream(); // throws IOException
+ AudioInputStream result = null;
+ try {
+ bis = new BufferedInputStream( urlStream, bisBufferSize );
+ result = getAudioInputStream( (InputStream)bis );
+ } finally {
+ if (result == null) {
+ urlStream.close();
+ }
+ }
+ return result;
+ }
+
+
+ /**
+ * Obtains an audio stream from the File provided. The File must
+ * point to valid audio file data.
+ * @param file the File for which the <code>AudioInputStream</code> should be
+ * constructed
+ * @return an <code>AudioInputStream</code> object based on the audio file data pointed
+ * to by the File
+ * @throws UnsupportedAudioFileException if the File does not point to valid audio
+ * file data recognized by the system
+ * @throws IOException if an I/O exception occurs
+ */
+ public AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException {
+
+ FileInputStream fis = null;
+ BufferedInputStream bis = null;
+ AudioFileFormat fileFormat = null;
+
+ fis = new FileInputStream( file ); // throws IOException
+ AudioInputStream result = null;
+ // part of fix for 4325421
+ try {
+ bis = new BufferedInputStream( fis, bisBufferSize );
+ result = getAudioInputStream( (InputStream)bis );
+ } finally {
+ if (result == null) {
+ fis.close();
+ }
+ }
+
+ return result;
+ }
+
+
+
+}