1 /* 2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.media.sound; 27 28 import java.io.DataInputStream; 29 import java.io.EOFException; 30 import java.io.File; 31 import java.io.FileInputStream; 32 import java.io.IOException; 33 import java.io.InputStream; 34 import java.net.URL; 35 36 import javax.sound.sampled.AudioFileFormat; 37 import javax.sound.sampled.AudioFormat; 38 import javax.sound.sampled.AudioInputStream; 39 import javax.sound.sampled.AudioSystem; 40 import javax.sound.sampled.UnsupportedAudioFileException; 41 42 43 44 /** 45 * WAVE file reader. 46 * 47 * @author Kara Kytle 48 * @author Jan Borgersen 49 * @author Florian Bomers 50 */ 51 public final class WaveFileReader extends SunFileReader { 52 53 private static final int MAX_READ_LENGTH = 12; 54 55 /** 56 * Obtains the audio file format of the input stream provided. The stream must 57 * point to valid audio file data. In general, audio file providers may 58 * need to read some data from the stream before determining whether they 59 * support it. These parsers must 60 * be able to mark the stream, read enough data to determine whether they 61 * support the stream, and, if not, reset the stream's read pointer to its original 62 * position. If the input stream does not support this, this method may fail 63 * with an IOException. 64 * @param stream the input stream from which file format information should be 65 * extracted 66 * @return an <code>AudioFileFormat</code> object describing the audio file format 67 * @throws UnsupportedAudioFileException if the stream does not point to valid audio 68 * file data recognized by the system 69 * @throws IOException if an I/O exception occurs 70 * @see InputStream#markSupported 71 * @see InputStream#mark 72 */ 73 public AudioFileFormat getAudioFileFormat(InputStream stream) throws UnsupportedAudioFileException, IOException { 74 // fix for 4489272: AudioSystem.getAudioFileFormat() fails for InputStream, but works for URL 75 AudioFileFormat aff = getFMT(stream, true); 76 // the following is not strictly necessary - but was implemented like that in 1.3.0 - 1.4.1 77 // so I leave it as it was. May remove this for 1.5.0 78 stream.reset(); 79 return aff; 80 } 81 82 83 /** 84 * Obtains the audio file format of the URL provided. The URL must 85 * point to valid audio file data. 86 * @param url the URL from which file format information should be 87 * extracted 88 * @return an <code>AudioFileFormat</code> object describing the audio file format 89 * @throws UnsupportedAudioFileException if the URL does not point to valid audio 90 * file data recognized by the system 91 * @throws IOException if an I/O exception occurs 92 */ 93 public AudioFileFormat getAudioFileFormat(URL url) throws UnsupportedAudioFileException, IOException { 94 InputStream urlStream = url.openStream(); // throws IOException 95 AudioFileFormat fileFormat = null; 96 try { 97 fileFormat = getFMT(urlStream, false); 98 } finally { 99 urlStream.close(); 100 } 101 return fileFormat; 102 } 103 104 105 /** 106 * Obtains the audio file format of the File provided. The File must 107 * point to valid audio file data. 108 * @param file the File from which file format information should be 109 * extracted 110 * @return an <code>AudioFileFormat</code> object describing the audio file format 111 * @throws UnsupportedAudioFileException if the File does not point to valid audio 112 * file data recognized by the system 113 * @throws IOException if an I/O exception occurs 114 */ 115 public AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException { 116 AudioFileFormat fileFormat = null; 117 FileInputStream fis = new FileInputStream(file); // throws IOException 118 // part of fix for 4325421 119 try { 120 fileFormat = getFMT(fis, false); 121 } finally { 122 fis.close(); 123 } 124 125 return fileFormat; 126 } 127 128 129 /** 130 * Obtains an audio stream from the input stream provided. The stream must 131 * point to valid audio file data. In general, audio file providers may 132 * need to read some data from the stream before determining whether they 133 * support it. These parsers must 134 * be able to mark the stream, read enough data to determine whether they 135 * support the stream, and, if not, reset the stream's read pointer to its original 136 * position. If the input stream does not support this, this method may fail 137 * with an IOException. 138 * @param stream the input stream from which the <code>AudioInputStream</code> should be 139 * constructed 140 * @return an <code>AudioInputStream</code> object based on the audio file data contained 141 * in the input stream. 142 * @throws UnsupportedAudioFileException if the stream does not point to valid audio 143 * file data recognized by the system 144 * @throws IOException if an I/O exception occurs 145 * @see InputStream#markSupported 146 * @see InputStream#mark 147 */ 148 public AudioInputStream getAudioInputStream(InputStream stream) throws UnsupportedAudioFileException, IOException { 149 // getFMT leaves the input stream at the beginning of the audio data 150 AudioFileFormat fileFormat = getFMT(stream, true); // throws UnsupportedAudioFileException, IOException 151 152 // we've got everything, and the stream is at the 153 // beginning of the audio data, so return an AudioInputStream. 154 return new AudioInputStream(stream, fileFormat.getFormat(), fileFormat.getFrameLength()); 155 } 156 157 158 /** 159 * Obtains an audio stream from the URL provided. The URL must 160 * point to valid audio file data. 161 * @param url the URL for which the <code>AudioInputStream</code> should be 162 * constructed 163 * @return an <code>AudioInputStream</code> object based on the audio file data pointed 164 * to by the URL 165 * @throws UnsupportedAudioFileException if the URL does not point to valid audio 166 * file data recognized by the system 167 * @throws IOException if an I/O exception occurs 168 */ 169 public AudioInputStream getAudioInputStream(URL url) throws UnsupportedAudioFileException, IOException { 170 InputStream urlStream = url.openStream(); // throws IOException 171 AudioFileFormat fileFormat = null; 172 try { 173 fileFormat = getFMT(urlStream, false); 174 } finally { 175 if (fileFormat == null) { 176 urlStream.close(); 177 } 178 } 179 return new AudioInputStream(urlStream, fileFormat.getFormat(), fileFormat.getFrameLength()); 180 } 181 182 183 /** 184 * Obtains an audio stream from the File provided. The File must 185 * point to valid audio file data. 186 * @param file the File for which the <code>AudioInputStream</code> should be 187 * constructed 188 * @return an <code>AudioInputStream</code> object based on the audio file data pointed 189 * to by the File 190 * @throws UnsupportedAudioFileException if the File does not point to valid audio 191 * file data recognized by the system 192 * @throws IOException if an I/O exception occurs 193 */ 194 public AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException { 195 FileInputStream fis = new FileInputStream(file); // throws IOException 196 AudioFileFormat fileFormat = null; 197 // part of fix for 4325421 198 try { 199 fileFormat = getFMT(fis, false); 200 } finally { 201 if (fileFormat == null) { 202 fis.close(); 203 } 204 } 205 return new AudioInputStream(fis, fileFormat.getFormat(), fileFormat.getFrameLength()); 206 } 207 208 209 //-------------------------------------------------------------------- 210 211 212 private AudioFileFormat getFMT(InputStream stream, boolean doReset) throws UnsupportedAudioFileException, IOException { 213 214 // assumes sream is rewound 215 216 int bytesRead; 217 int nread = 0; 218 int fmt; 219 int length = 0; 220 int wav_type = 0; 221 short channels; 222 long sampleRate; 223 long avgBytesPerSec; 224 short blockAlign; 225 int sampleSizeInBits; 226 AudioFormat.Encoding encoding = null; 227 228 DataInputStream dis = new DataInputStream( stream ); 229 230 if (doReset) { 231 dis.mark(MAX_READ_LENGTH); 232 } 233 234 int magic = dis.readInt(); 235 int fileLength = rllong(dis); 236 int waveMagic = dis.readInt(); 237 int totallength; 238 if (fileLength <= 0) { 239 fileLength = AudioSystem.NOT_SPECIFIED; 240 totallength = AudioSystem.NOT_SPECIFIED; 241 } else { 242 totallength = fileLength + 8; 243 } 244 245 if ((magic != WaveFileFormat.RIFF_MAGIC) || (waveMagic != WaveFileFormat.WAVE_MAGIC)) { 246 // not WAVE, throw UnsupportedAudioFileException 247 if (doReset) { 248 dis.reset(); 249 } 250 throw new UnsupportedAudioFileException("not a WAVE file"); 251 } 252 253 // find and read the "fmt" chunk 254 // we break out of this loop either by hitting EOF or finding "fmt " 255 while(true) { 256 257 try { 258 fmt = dis.readInt(); 259 nread += 4; 260 if( fmt==WaveFileFormat.FMT_MAGIC ) { 261 // we've found the 'fmt' chunk 262 break; 263 } else { 264 // else not 'fmt', skip this chunk 265 length = rllong(dis); 266 nread += 4; 267 if (length % 2 > 0) length++; 268 nread += dis.skipBytes(length); 269 } | 1 /* 2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.media.sound; 27 28 import java.io.DataInputStream; 29 import java.io.EOFException; 30 import java.io.IOException; 31 import java.io.InputStream; 32 33 import javax.sound.sampled.AudioFileFormat; 34 import javax.sound.sampled.AudioFormat; 35 import javax.sound.sampled.AudioSystem; 36 import javax.sound.sampled.UnsupportedAudioFileException; 37 38 /** 39 * WAVE file reader. 40 * 41 * @author Kara Kytle 42 * @author Jan Borgersen 43 * @author Florian Bomers 44 */ 45 public final class WaveFileReader extends SunFileReader { 46 47 @Override 48 AudioFileFormat getAudioFileFormatImpl(final InputStream stream) 49 throws UnsupportedAudioFileException, IOException { 50 51 // assumes sream is rewound 52 53 int nread = 0; 54 int fmt; 55 int length = 0; 56 int wav_type = 0; 57 short channels; 58 long sampleRate; 59 long avgBytesPerSec; 60 short blockAlign; 61 int sampleSizeInBits; 62 AudioFormat.Encoding encoding = null; 63 64 DataInputStream dis = new DataInputStream( stream ); 65 66 int magic = dis.readInt(); 67 int fileLength = rllong(dis); 68 int waveMagic = dis.readInt(); 69 int totallength; 70 if (fileLength <= 0) { 71 fileLength = AudioSystem.NOT_SPECIFIED; 72 totallength = AudioSystem.NOT_SPECIFIED; 73 } else { 74 totallength = fileLength + 8; 75 } 76 77 if ((magic != WaveFileFormat.RIFF_MAGIC) || (waveMagic != WaveFileFormat.WAVE_MAGIC)) { 78 // not WAVE, throw UnsupportedAudioFileException 79 throw new UnsupportedAudioFileException("not a WAVE file"); 80 } 81 82 // find and read the "fmt" chunk 83 // we break out of this loop either by hitting EOF or finding "fmt " 84 while(true) { 85 86 try { 87 fmt = dis.readInt(); 88 nread += 4; 89 if( fmt==WaveFileFormat.FMT_MAGIC ) { 90 // we've found the 'fmt' chunk 91 break; 92 } else { 93 // else not 'fmt', skip this chunk 94 length = rllong(dis); 95 nread += 4; 96 if (length % 2 > 0) length++; 97 nread += dis.skipBytes(length); 98 } |