1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52:
53:
67: public class WAVReader extends AudioFileReader
68: {
69: private static long readUnsignedIntLE (DataInputStream is)
70: throws IOException
71: {
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));
78: }
79:
80: private static short readUnsignedShortLE (DataInputStream is)
81: throws IOException
82: {
83: byte[] buf = new byte[2];
84: is.readFully(buf);
85: return (short) (buf[0] & 0xFF
86: | ((buf[1] & 0xFF) << 8));
87: }
88:
89:
92: public AudioFileFormat getAudioFileFormat(File file)
93: throws UnsupportedAudioFileException, IOException
94: {
95: InputStream is = new FileInputStream(file);
96: try
97: {
98: return getAudioFileFormat(is);
99: }
100: finally
101: {
102: is.close();
103: }
104: }
105:
106:
109: public AudioFileFormat getAudioFileFormat(InputStream in)
110: throws UnsupportedAudioFileException, IOException
111: {
112: DataInputStream din;
113:
114: if (in instanceof DataInputStream)
115: din = (DataInputStream) in;
116: else
117: din = new DataInputStream(in);
118:
119: if (din.readInt() != 0x52494646)
120: throw new UnsupportedAudioFileException("Invalid WAV chunk header.");
121:
122:
123: readUnsignedIntLE(din);
124:
125: if (din.readInt() != 0x57415645)
126: throw new UnsupportedAudioFileException("Invalid WAV chunk header.");
127:
128: boolean foundFmt = false;
129: boolean foundData = false;
130:
131: short compressionCode = 0, numberChannels = 0, bitsPerSample = 0;
132: long sampleRate = 0, bytesPerSecond = 0;
133: long chunkLength = 0;
134:
135: while (! foundData)
136: {
137: int chunkId = din.readInt();
138: chunkLength = readUnsignedIntLE(din);
139: switch (chunkId)
140: {
141: case 0x666D7420:
142: foundFmt = true;
143: compressionCode = readUnsignedShortLE(din);
144: numberChannels = readUnsignedShortLE(din);
145: sampleRate = readUnsignedIntLE(din);
146: bytesPerSecond = readUnsignedIntLE(din);
147: readUnsignedShortLE(din);
148: bitsPerSample = readUnsignedShortLE(din);
149: din.skip(chunkLength - 16);
150: break;
151: case 0x66616374:
152:
153: din.skip(chunkLength);
154: break;
155: case 0x64617461:
156: if (! foundFmt)
157: throw new UnsupportedAudioFileException("This implementation requires WAV fmt chunks precede data chunks.");
158: foundData = true;
159: break;
160: default:
161:
162: din.skip(chunkLength);
163: }
164: }
165:
166: AudioFormat.Encoding encoding;
167:
168: switch (compressionCode)
169: {
170: case 1:
171: if (bitsPerSample <= 8)
172: encoding = AudioFormat.Encoding.PCM_UNSIGNED;
173: else
174: encoding = AudioFormat.Encoding.PCM_SIGNED;
175: break;
176:
177: default:
178: throw new UnsupportedAudioFileException("Unrecognized WAV compression code: 0x"
179: + Integer.toHexString(compressionCode));
180: }
181:
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);
190: }
191:
192:
195: public AudioFileFormat getAudioFileFormat(URL url)
196: throws UnsupportedAudioFileException, IOException
197: {
198: InputStream is = url.openStream();
199: try
200: {
201: return getAudioFileFormat(is);
202: }
203: finally
204: {
205: is.close();
206: }
207: }
208:
209:
212: public AudioInputStream getAudioInputStream(File file)
213: throws UnsupportedAudioFileException, IOException
214: {
215: return getAudioInputStream(new FileInputStream(file));
216: }
217:
218:
221: public AudioInputStream getAudioInputStream(InputStream stream)
222: throws UnsupportedAudioFileException, IOException
223: {
224: AudioFileFormat aff = getAudioFileFormat(stream);
225: return new AudioInputStream(stream, aff.getFormat(), (long) aff.getFrameLength());
226: }
227:
228:
231: public AudioInputStream getAudioInputStream(URL url)
232: throws UnsupportedAudioFileException, IOException
233: {
234: return getAudioInputStream(url.openStream());
235: }
236: }