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