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