1 /*
2 * Copyright 1999-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package javax.sound.sampled;
27
28 import java.io.File;
29 import java.io.OutputStream;
30 import java.io.IOException;
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.Map;
34
35
36 /**
37 * An instance of the <code>AudioFileFormat</code> class describes
38 * an audio file, including the file type, the file's length in bytes,
39 * the length in sample frames of the audio data contained in the file,
40 * and the format of the audio data.
41 * <p>
42 * The <code>{@link AudioSystem}</code> class includes methods for determining the format
43 * of an audio file, obtaining an audio input stream from an audio file, and
44 * writing an audio file from an audio input stream.
45 *
46 * <p>An <code>AudioFileFormat</code> object can
47 * include a set of properties. A property is a pair of key and value:
48 * the key is of type <code>String</code>, the associated property
49 * value is an arbitrary object.
50 * Properties specify additional informational
51 * meta data (like a author, copyright, or file duration).
52 * Properties are optional information, and file reader and file
53 * writer implementations are not required to provide or
54 * recognize properties.
55 *
56 * <p>The following table lists some common properties that should
57 * be used in implementations:
58 *
59 * <table border=1>
60 * <tr>
61 * <th>Property key</th>
62 * <th>Value type</th>
63 * <th>Description</th>
64 * </tr>
65 * <tr>
66 * <td>"duration"</td>
67 * <td>{@link java.lang.Long Long}</td>
68 * <td>playback duration of the file in microseconds</td>
69 * </tr>
70 * <tr>
71 * <td>"author"</td>
72 * <td>{@link java.lang.String String}</td>
73 * <td>name of the author of this file</td>
74 * </tr>
75 * <tr>
76 * <td>"title"</td>
77 * <td>{@link java.lang.String String}</td>
78 * <td>title of this file</td>
79 * </tr>
80 * <tr>
81 * <td>"copyright"</td>
82 * <td>{@link java.lang.String String}</td>
83 * <td>copyright message</td>
84 * </tr>
85 * <tr>
86 * <td>"date"</td>
87 * <td>{@link java.util.Date Date}</td>
88 * <td>date of the recording or release</td>
89 * </tr>
90 * <tr>
91 * <td>"comment"</td>
92 * <td>{@link java.lang.String String}</td>
93 * <td>an arbitrary text</td>
94 * </tr>
95 * </table>
96 *
97 *
98 * @author David Rivas
99 * @author Kara Kytle
100 * @author Florian Bomers
101 * @see AudioInputStream
102 * @since 1.3
103 */
104 public class AudioFileFormat {
105
106
107 // INSTANCE VARIABLES
108
109
110 /**
111 * File type.
112 */
113 private Type type;
114
115 /**
116 * File length in bytes
117 */
118 private int byteLength;
119
120 /**
121 * Format of the audio data contained in the file.
122 */
123 private AudioFormat format;
124
125 /**
126 * Audio data length in sample frames
127 */
128 private int frameLength;
129
130
131 /** The set of properties */
132 private HashMap<String, Object> properties;
133
134
135 /**
136 * Constructs an audio file format object.
137 * This protected constructor is intended for use by providers of file-reading
138 * services when returning information about an audio file or about supported audio file
139 * formats.
140 * @param type the type of the audio file
141 * @param byteLength the length of the file in bytes, or <code>AudioSystem.NOT_SPECIFIED</code>
142 * @param format the format of the audio data contained in the file
143 * @param frameLength the audio data length in sample frames, or <code>AudioSystem.NOT_SPECIFIED</code>
144 *
145 * @see #getType
146 */
147 protected AudioFileFormat(Type type, int byteLength, AudioFormat format, int frameLength) {
148
149 this.type = type;
150 this.byteLength = byteLength;
151 this.format = format;
152 this.frameLength = frameLength;
153 this.properties = null;
154 }
155
156
157 /**
158 * Constructs an audio file format object.
159 * This public constructor may be used by applications to describe the
160 * properties of a requested audio file.
161 * @param type the type of the audio file
162 * @param format the format of the audio data contained in the file
163 * @param frameLength the audio data length in sample frames, or <code>AudioSystem.NOT_SPECIFIED</code>
164 */
165 public AudioFileFormat(Type type, AudioFormat format, int frameLength) {
166
167
168 this(type,AudioSystem.NOT_SPECIFIED,format,frameLength);
169 }
170
171 /**
172 * Construct an audio file format object with a set of
173 * defined properties.
174 * This public constructor may be used by applications to describe the
175 * properties of a requested audio file. The properties map
176 * will be copied to prevent any changes to it.
177 *
178 * @param type the type of the audio file
179 * @param format the format of the audio data contained in the file
180 * @param frameLength the audio data length in sample frames, or
181 * <code>AudioSystem.NOT_SPECIFIED</code>
182 * @param properties a <code>Map<String,Object></code> object
183 * with properties
184 *
185 * @since 1.5
186 */
187 public AudioFileFormat(Type type, AudioFormat format,
188 int frameLength, Map<String, Object> properties) {
189 this(type,AudioSystem.NOT_SPECIFIED,format,frameLength);
190 this.properties = new HashMap<String, Object>(properties);
191 }
192
193
194 /**
195 * Obtains the audio file type, such as <code>WAVE</code> or <code>AU</code>.
196 * @return the audio file type
197 *
198 * @see Type#WAVE
199 * @see Type#AU
200 * @see Type#AIFF
201 * @see Type#AIFC
202 * @see Type#SND
203 */
204 public Type getType() {
205 return type;
206 }
207
208 /**
209 * Obtains the size in bytes of the entire audio file (not just its audio data).
210 * @return the audio file length in bytes
211 * @see AudioSystem#NOT_SPECIFIED
212 */
213 public int getByteLength() {
214 return byteLength;
215 }
216
217 /**
218 * Obtains the format of the audio data contained in the audio file.
219 * @return the audio data format
220 */
221 public AudioFormat getFormat() {
222 return format;
223 }
224
225 /**
226 * Obtains the length of the audio data contained in the file, expressed in sample frames.
227 * @return the number of sample frames of audio data in the file
228 * @see AudioSystem#NOT_SPECIFIED
229 */
230 public int getFrameLength() {
231 return frameLength;
232 }
233
234 /**
235 * Obtain an unmodifiable map of properties.
236 * The concept of properties is further explained in
237 * the {@link AudioFileFormat class description}.
238 *
239 * @return a <code>Map<String,Object></code> object containing
240 * all properties. If no properties are recognized, an empty map is
241 * returned.
242 *
243 * @see #getProperty(String)
244 * @since 1.5
245 */
246 public Map<String,Object> properties() {
247 Map<String,Object> ret;
248 if (properties == null) {
249 ret = new HashMap<String,Object>(0);
250 } else {
251 ret = (Map<String,Object>) (properties.clone());
252 }
253 return (Map<String,Object>) Collections.unmodifiableMap(ret);
254 }
255
256
257 /**
258 * Obtain the property value specified by the key.
259 * The concept of properties is further explained in
260 * the {@link AudioFileFormat class description}.
261 *
262 * <p>If the specified property is not defined for a
263 * particular file format, this method returns
264 * <code>null</code>.
265 *
266 * @param key the key of the desired property
267 * @return the value of the property with the specified key,
268 * or <code>null</code> if the property does not exist.
269 *
270 * @see #properties()
271 * @since 1.5
272 */
273 public Object getProperty(String key) {
274 if (properties == null) {
275 return null;
276 }
277 return properties.get(key);
278 }
279
280
281 /**
282 * Provides a string representation of the file format.
283 * @return the file format as a string
284 */
285 public String toString() {
286
287 StringBuffer buf = new StringBuffer();
288
289 //$$fb2002-11-01: fix for 4672864: AudioFileFormat.toString() throws unexpected NullPointerException
290 if (type != null) {
291 buf.append(type.toString() + " (." + type.getExtension() + ") file");
292 } else {
293 buf.append("unknown file format");
294 }
295
296 if (byteLength != AudioSystem.NOT_SPECIFIED) {
297 buf.append(", byte length: " + byteLength);
298 }
299
300 buf.append(", data format: " + format);
301
302 if (frameLength != AudioSystem.NOT_SPECIFIED) {
303 buf.append(", frame length: " + frameLength);
304 }
305
306 return new String(buf);
307 }
308
309
310 /**
311 * An instance of the <code>Type</code> class represents one of the
312 * standard types of audio file. Static instances are provided for the
313 * common types.
314 */
315 public static class Type {
316
317 // FILE FORMAT TYPE DEFINES
318
319 /**
320 * Specifies a WAVE file.
321 */
322 public static final Type WAVE = new Type("WAVE", "wav");
323
324 /**
325 * Specifies an AU file.
326 */
327 public static final Type AU = new Type("AU", "au");
328
329 /**
330 * Specifies an AIFF file.
331 */
332 public static final Type AIFF = new Type("AIFF", "aif");
333
334 /**
335 * Specifies an AIFF-C file.
336 */
337 public static final Type AIFC = new Type("AIFF-C", "aifc");
338
339 /**
340 * Specifies a SND file.
341 */
342 public static final Type SND = new Type("SND", "snd");
343
344
345 // INSTANCE VARIABLES
346
347 /**
348 * File type name.
349 */
350 private final String name;
351
352 /**
353 * File type extension.
354 */
355 private final String extension;
356
357
358 // CONSTRUCTOR
359
360 /**
361 * Constructs a file type.
362 * @param name the string that names the file type
363 * @param extension the string that commonly marks the file type
364 * without leading dot.
365 */
366 public Type(String name, String extension) {
367
368 this.name = name;
369 this.extension = extension;
370 }
371
372
373 // METHODS
374
375 /**
376 * Finalizes the equals method
377 */
378 public final boolean equals(Object obj) {
379 if (toString() == null) {
380 return (obj != null) && (obj.toString() == null);
381 }
382 if (obj instanceof Type) {
383 return toString().equals(obj.toString());
384 }
385 return false;
386 }
387
388 /**
389 * Finalizes the hashCode method
390 */
391 public final int hashCode() {
392 if (toString() == null) {
393 return 0;
394 }
395 return toString().hashCode();
396 }
397
398 /**
399 * Provides the file type's name as the <code>String</code> representation
400 * of the file type.
401 * @return the file type's name
402 */
403 public final String toString() {
404 return name;
405 }
406
407 /**
408 * Obtains the common file name extension for this file type.
409 * @return file type extension
410 */
411 public String getExtension() {
412 return extension;
413 }
414
415 } // class Type
416
417 } // class AudioFileFormat