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