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