Import GNU Classpath (20121202).
[official-gcc.git] / libjava / classpath / gnu / javax / sound / sampled / WAV / WAVReader.java
blobf03bc4790adcaae9b897a077e8900a8c332aaf5d
1 /* WAVReader.java -- Read WAV files.
2 Copyright (C) 2006, 2012 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.javax.sound.sampled.WAV;
40 import java.io.File;
41 import java.io.IOException;
42 import java.io.InputStream;
43 import java.io.DataInputStream;
44 import java.io.FileInputStream;
45 import java.net.URL;
47 import javax.sound.sampled.AudioFormat;
48 import javax.sound.sampled.AudioFileFormat;
49 import javax.sound.sampled.AudioInputStream;
50 import javax.sound.sampled.UnsupportedAudioFileException;
51 import javax.sound.sampled.spi.AudioFileReader;
53 /**
54 * A WAV file reader.
56 * This code reads WAV files.
58 * There are many decent documents on the web describing the WAV file
59 * format. I didn't bother looking for the official document. If it
60 * exists, I'm not even sure if it is freely available. We should
61 * update this comment if we find out anything helpful here. I used
62 * http://www.sonicspot.com/guide/wavefiles.html
64 * @author Anthony Green (green@redhat.com)
67 public class WAVReader extends AudioFileReader
69 private static long readUnsignedIntLE (DataInputStream is)
70 throws IOException
72 byte[] buf = new byte[4];
73 is.readFully(buf);
74 return (buf[0] & 0xFF
75 | ((buf[1] & 0xFF) << 8)
76 | ((buf[2] & 0xFF) << 16)
77 | ((buf[3] & 0xFF) << 24));
80 private static short readUnsignedShortLE (DataInputStream is)
81 throws IOException
83 byte[] buf = new byte[2];
84 is.readFully(buf);
85 return (short) (buf[0] & 0xFF
86 | ((buf[1] & 0xFF) << 8));
89 /* Get an AudioFileFormat from the given File.
90 * @see javax.sound.sampled.spi.AudioFileReader#getAudioFileFormat(java.io.File)
92 public AudioFileFormat getAudioFileFormat(File file)
93 throws UnsupportedAudioFileException, IOException
95 InputStream is = new FileInputStream(file);
96 try
98 return getAudioFileFormat(is);
100 finally
102 is.close();
106 /* Get an AudioFileFormat from the given InputStream.
107 * @see javax.sound.sampled.spi.AudioFileReader#getAudioFileFormat(java.io.InputStream)
109 public AudioFileFormat getAudioFileFormat(InputStream in)
110 throws UnsupportedAudioFileException, IOException
112 DataInputStream din;
114 if (in instanceof DataInputStream)
115 din = (DataInputStream) in;
116 else
117 din = new DataInputStream(in);
119 if (din.readInt() != 0x52494646) // "RIFF"
120 throw new UnsupportedAudioFileException("Invalid WAV chunk header.");
122 // Read the length of this RIFF thing.
123 readUnsignedIntLE(din);
125 if (din.readInt() != 0x57415645) // "WAVE"
126 throw new UnsupportedAudioFileException("Invalid WAV chunk header.");
128 boolean foundFmt = false;
129 boolean foundData = false;
131 short compressionCode = 0, numberChannels = 0, bitsPerSample = 0;
132 long sampleRate = 0, bytesPerSecond = 0;
133 long chunkLength = 0;
135 while (! foundData)
137 int chunkId = din.readInt();
138 chunkLength = readUnsignedIntLE(din);
139 switch (chunkId)
141 case 0x666D7420: // "fmt "
142 foundFmt = true;
143 compressionCode = readUnsignedShortLE(din);
144 numberChannels = readUnsignedShortLE(din);
145 sampleRate = readUnsignedIntLE(din);
146 bytesPerSecond = readUnsignedIntLE(din);
147 readUnsignedShortLE(din); // blockAlign
148 bitsPerSample = readUnsignedShortLE(din);
149 din.skip(chunkLength - 16);
150 break;
151 case 0x66616374: // "fact"
152 // FIXME: hold compression format dependent data.
153 din.skip(chunkLength);
154 break;
155 case 0x64617461: // "data"
156 if (! foundFmt)
157 throw new UnsupportedAudioFileException("This implementation requires WAV fmt chunks precede data chunks.");
158 foundData = true;
159 break;
160 default:
161 // Unrecognized chunk. Skip it.
162 din.skip(chunkLength);
166 AudioFormat.Encoding encoding;
168 switch (compressionCode)
170 case 1: // PCM/uncompressed
171 if (bitsPerSample <= 8)
172 encoding = AudioFormat.Encoding.PCM_UNSIGNED;
173 else
174 encoding = AudioFormat.Encoding.PCM_SIGNED;
175 break;
177 default:
178 throw new UnsupportedAudioFileException("Unrecognized WAV compression code: 0x"
179 + Integer.toHexString(compressionCode));
182 return new AudioFileFormat (AudioFileFormat.Type.WAVE,
183 new AudioFormat(encoding,
184 (float) sampleRate,
185 bitsPerSample,
186 numberChannels,
187 ((bitsPerSample + 7) / 8) * numberChannels,
188 (float) bytesPerSecond, false),
189 (int) chunkLength);
192 /* Get an AudioFileFormat from the given URL.
193 * @see javax.sound.sampled.spi.AudioFileReader#getAudioFileFormat(java.net.URL)
195 public AudioFileFormat getAudioFileFormat(URL url)
196 throws UnsupportedAudioFileException, IOException
198 InputStream is = url.openStream();
201 return getAudioFileFormat(is);
203 finally
205 is.close();
209 /* Get an AudioInputStream from the given File.
210 * @see javax.sound.sampled.spi.AudioFileReader#getAudioInputStream(java.io.File)
212 public AudioInputStream getAudioInputStream(File file)
213 throws UnsupportedAudioFileException, IOException
215 return getAudioInputStream(new FileInputStream(file));
218 /* Get an AudioInputStream from the given InputStream.
219 * @see javax.sound.sampled.spi.AudioFileReader#getAudioInputStream(java.io.InputStream)
221 public AudioInputStream getAudioInputStream(InputStream stream)
222 throws UnsupportedAudioFileException, IOException
224 AudioFileFormat aff = getAudioFileFormat(stream);
225 return new AudioInputStream(stream, aff.getFormat(), (long) aff.getFrameLength());
228 /* Get an AudioInputStream from the given URL.
229 * @see javax.sound.sampled.spi.AudioFileReader#getAudioInputStream(java.net.URL)
231 public AudioInputStream getAudioInputStream(URL url)
232 throws UnsupportedAudioFileException, IOException
234 return getAudioInputStream(url.openStream());