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.midi; 27 28 import java.io.InputStream; 29 import java.io.IOException; 30 import java.util.Collections; 31 import java.util.HashMap; 32 import java.util.Map; 33 34 35 /** 36 * A <code>MidiFileFormat</code> object encapsulates a MIDI file's 37 * type, as well as its length and timing information. 38 * 39 * <p>A <code>MidiFileFormat</code> object can 40 * include a set of properties. A property is a pair of key and value: 41 * the key is of type <code>String</code>, the associated property 42 * value is an arbitrary object. 43 * Properties specify additional informational 44 * meta data (like a author, or copyright). 45 * Properties are optional information, and file reader and file 46 * writer implementations are not required to provide or 47 * recognize properties. 48 * 49 * <p>The following table lists some common properties that should 50 * be used in implementations: 51 * 52 * <table border=1> 53 * <tr> 54 * <th>Property key</th> 55 * <th>Value type</th> 56 * <th>Description</th> 57 * </tr> 58 * <tr> 59 * <td>"author"</td> 60 * <td>{@link java.lang.String String}</td> 61 * <td>name of the author of this file</td> 62 * </tr> 63 * <tr> 64 * <td>"title"</td> 65 * <td>{@link java.lang.String String}</td> 66 * <td>title of this file</td> 67 * </tr> 68 * <tr> 69 * <td>"copyright"</td> 70 * <td>{@link java.lang.String String}</td> 71 * <td>copyright message</td> 72 * </tr> 73 * <tr> 74 * <td>"date"</td> 75 * <td>{@link java.util.Date Date}</td> 76 * <td>date of the recording or release</td> 77 * </tr> 78 * <tr> 79 * <td>"comment"</td> 80 * <td>{@link java.lang.String String}</td> 81 * <td>an arbitrary text</td> 82 * </tr> 83 * </table> 84 * 85 * @see MidiSystem#getMidiFileFormat(java.io.File) 86 * @see Sequencer#setSequence(java.io.InputStream stream) 87 * 88 * @author Kara Kytle 89 * @author Florian Bomers 90 */ 91 92 public class MidiFileFormat { 93 94 95 /** 96 * Represents unknown length. 97 * @see #getByteLength 98 * @see #getMicrosecondLength 99 */ 100 public static final int UNKNOWN_LENGTH = -1; 101 102 103 /** 104 * The type of MIDI file. 105 */ 106 protected int type; 107 108 /** 109 * The division type of the MIDI file. 110 * 111 * @see Sequence#PPQ 112 * @see Sequence#SMPTE_24 113 * @see Sequence#SMPTE_25 114 * @see Sequence#SMPTE_30DROP 115 * @see Sequence#SMPTE_30 116 */ 117 protected float divisionType; 118 119 /** 120 * The timing resolution of the MIDI file. 121 */ 122 protected int resolution; 123 124 /** 125 * The length of the MIDI file in bytes. 126 */ 127 protected int byteLength; 128 129 /** 130 * The duration of the MIDI file in microseconds. 131 */ 132 protected long microsecondLength; 133 134 135 /** The set of properties */ 136 private HashMap<String, Object> properties; 137 138 139 /** 140 * Constructs a <code>MidiFileFormat</code>. 141 * 142 * @param type the MIDI file type (0, 1, or 2) 143 * @param divisionType the timing division type (PPQ or one of the SMPTE types) 144 * @param resolution the timing resolution 145 * @param bytes the length of the MIDI file in bytes, or UNKNOWN_LENGTH if not known 146 * @param microseconds the duration of the file in microseconds, or UNKNOWN_LENGTH if not known 147 * @see #UNKNOWN_LENGTH 148 * @see Sequence#PPQ 149 * @see Sequence#SMPTE_24 150 * @see Sequence#SMPTE_25 151 * @see Sequence#SMPTE_30DROP 152 * @see Sequence#SMPTE_30 153 */ 154 public MidiFileFormat(int type, float divisionType, int resolution, int bytes, long microseconds) { 155 156 this.type = type; 157 this.divisionType = divisionType; 158 this.resolution = resolution; 159 this.byteLength = bytes; 160 this.microsecondLength = microseconds; 161 this.properties = null; 162 } 163 164 165 /** 166 * Construct a <code>MidiFileFormat</code> with a set of properties. 167 * 168 * @param type the MIDI file type (0, 1, or 2) 169 * @param divisionType the timing division type 170 * (PPQ or one of the SMPTE types) 171 * @param resolution the timing resolution 172 * @param bytes the length of the MIDI file in bytes, 173 * or UNKNOWN_LENGTH if not known 174 * @param microseconds the duration of the file in microseconds, 175 * or UNKNOWN_LENGTH if not known 176 * @param properties a <code>Map<String,Object></code> object 177 * with properties 178 * 179 * @see #UNKNOWN_LENGTH 180 * @see Sequence#PPQ 181 * @see Sequence#SMPTE_24 182 * @see Sequence#SMPTE_25 183 * @see Sequence#SMPTE_30DROP 184 * @see Sequence#SMPTE_30 185 * @since 1.5 186 */ 187 public MidiFileFormat(int type, float divisionType, 188 int resolution, int bytes, 189 long microseconds, Map<String, Object> properties) { 190 this(type, divisionType, resolution, bytes, microseconds); 191 this.properties = new HashMap<String, Object>(properties); 192 } 193 194 195 196 /** 197 * Obtains the MIDI file type. 198 * @return the file's type (0, 1, or 2) 199 */ 200 public int getType() { 201 return type; 202 } 203 204 /** 205 * Obtains the timing division type for the MIDI file. 206 * 207 * @return the division type (PPQ or one of the SMPTE types) 208 * 209 * @see Sequence#Sequence(float, int) 210 * @see Sequence#PPQ 211 * @see Sequence#SMPTE_24 212 * @see Sequence#SMPTE_25 213 * @see Sequence#SMPTE_30DROP 214 * @see Sequence#SMPTE_30 215 * @see Sequence#getDivisionType() 216 */ 217 public float getDivisionType() { 218 return divisionType; 219 } 220 221 222 /** 223 * Obtains the timing resolution for the MIDI file. 224 * If the division type is PPQ, the resolution is specified in ticks per beat. 225 * For SMTPE timing, the resolution is specified in ticks per frame. 226 * 227 * @return the number of ticks per beat (PPQ) or per frame (SMPTE) 228 * @see #getDivisionType 229 * @see Sequence#getResolution() 230 */ 231 public int getResolution() { 232 return resolution; 233 } 234 235 236 /** 237 * Obtains the length of the MIDI file, expressed in 8-bit bytes. 238 * @return the number of bytes in the file, or UNKNOWN_LENGTH if not known 239 * @see #UNKNOWN_LENGTH 240 */ 241 public int getByteLength() { 242 return byteLength; 243 } 244 245 /** 246 * Obtains the length of the MIDI file, expressed in microseconds. 247 * @return the file's duration in microseconds, or UNKNOWN_LENGTH if not known 248 * @see Sequence#getMicrosecondLength() 249 * @see #getByteLength 250 * @see #UNKNOWN_LENGTH 251 */ 252 public long getMicrosecondLength() { 253 return microsecondLength; 254 } 255 256 /** 257 * Obtain an unmodifiable map of properties. 258 * The concept of properties is further explained in 259 * the {@link MidiFileFormat class description}. 260 * 261 * @return a <code>Map<String,Object></code> object containing 262 * all properties. If no properties are recognized, an empty map is 263 * returned. 264 * 265 * @see #getProperty(String) 266 * @since 1.5 267 */ 268 public Map<String,Object> properties() { 269 Map<String,Object> ret; 270 if (properties == null) { 271 ret = new HashMap<String,Object>(0); 272 } else { 273 ret = (Map<String,Object>) (properties.clone()); 274 } 275 return (Map<String,Object>) Collections.unmodifiableMap(ret); 276 } 277 278 279 /** 280 * Obtain the property value specified by the key. 281 * The concept of properties is further explained in 282 * the {@link MidiFileFormat class description}. 283 * 284 * <p>If the specified property is not defined for a 285 * particular file format, this method returns 286 * <code>null</code>. 287 * 288 * @param key the key of the desired property 289 * @return the value of the property with the specified key, 290 * or <code>null</code> if the property does not exist. 291 * 292 * @see #properties() 293 * @since 1.5 294 */ 295 public Object getProperty(String key) { 296 if (properties == null) { 297 return null; 298 } 299 return properties.get(key); 300 } 301 302 303 }