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