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