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