1 /* 2 * Copyright (c) 1999, 2007, 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 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