1. /*
  2. * @(#)MidiMessage.java 1.28 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.sound.midi;
  8. /**
  9. * <code>MidiMessage</code> is the base class for MIDI messages. They include
  10. * not only the standard MIDI messages that a synthesizer can respond to, but also
  11. * "meta-events" that can be used by sequencer programs. There are meta-events
  12. * for such information as lyrics, copyrights, tempo indications, time and key
  13. * signatures, markers, etc. For more information, see the Standard MIDI Files 1.0
  14. * specification, which is part of the Complete MIDI 1.0 Detailed Specification
  15. * published by the MIDI Manufacturer's Association
  16. * (<a href = http://www.midi.org>http://www.midi.org</a>).
  17. * <p>
  18. * The base <code>MidiMessage</code> class provides access to three types of
  19. * information about a MIDI message:
  20. * <ul>
  21. * <li>The messages's status byte</li>
  22. * <li>The total length of the message in bytes (the status byte plus any data bytes)</li>
  23. * <li>A byte array containing the complete message</li>
  24. * </ul>
  25. *
  26. * <code>MidiMessage</code> includes methods to get, but not set, these values.
  27. * Setting them is a subclass responsibility.
  28. * <p>
  29. * <a name="integersVsBytes"></a>
  30. * The MIDI standard expresses MIDI data in bytes. However, because
  31. * Java<sup>TM</sup> uses signed bytes, the Java Sound API uses integers
  32. * instead of bytes when expressing MIDI data. For example, the
  33. * {@link #getStatus()} method of
  34. * <code>MidiMessage</code> returns MIDI status bytes as integers. If you are
  35. * processing MIDI data that originated outside Java Sound and now
  36. * is encoded as signed bytes, the bytes can
  37. * can be converted to integers using this conversion:
  38. * <center><code>int i = (int)(byte & 0xFF)</code></center>
  39. * <p>
  40. * If you simply need to pass a known MIDI byte value as a method parameter,
  41. * it can be expressed directly as an integer, using (for example) decimal or
  42. * hexidecimal notation. For instance, to pass the "active sensing" status byte
  43. * as the first argument to ShortMessage's
  44. * {@link ShortMessage#setMessage(int) setMessage(int)}
  45. * method, you can express it as 254 or 0xFE.
  46. *
  47. * @see Track
  48. * @see Sequence
  49. * @see Receiver
  50. *
  51. * @version 1.28, 03/01/23
  52. * @author David Rivas
  53. * @author Kara Kytle
  54. */
  55. public abstract class MidiMessage implements Cloneable {
  56. // Instance variables
  57. /**
  58. * The MIDI message data. The first byte is the status
  59. * byte for the message; subsequent bytes up to the length
  60. * of the message are data bytes for this message.
  61. * @see #getLength
  62. */
  63. protected byte[] data;
  64. /**
  65. * The number of bytes in the MIDI message, including the
  66. * status byte and any data bytes.
  67. * @see #getLength
  68. */
  69. protected int length = 0;
  70. /**
  71. * Constructs a new <code>MidiMessage</code>. This protected
  72. * constructor is called by concrete subclasses, which should
  73. * ensure that the data array specifies a complete, valid MIDI
  74. * message.
  75. *
  76. * @param data an array of bytes containing the complete message.
  77. * The message data may be changed using the <code>setMessage</code>
  78. * method.
  79. *
  80. * @see #setMessage
  81. */
  82. protected MidiMessage(byte[] data) {
  83. this.data = data;
  84. if (data != null) {
  85. this.length = data.length;
  86. }
  87. }
  88. /**
  89. * Sets the data for the MIDI message. This protected
  90. * method is called by concrete subclasses, which should
  91. * ensure that the data array specifies a complete, valid MIDI
  92. * message.
  93. */
  94. protected void setMessage(byte[] data, int length) throws InvalidMidiDataException {
  95. if (length < 0 || (length > 0 && length > data.length)) {
  96. throw new IndexOutOfBoundsException("length out of bounds: "+length);
  97. }
  98. this.length = length;
  99. if (this.data == null || this.data.length < this.length) {
  100. this.data = new byte[this.length];
  101. }
  102. System.arraycopy(data, 0, this.data, 0, length);
  103. }
  104. /**
  105. * Obtains the MIDI message data. The first byte of the returned byte
  106. * array is the status byte of the message. Any subsequent bytes up to
  107. * the length of the message are data bytes. The byte array may have a
  108. * length which is greater than that of the actual message; the total
  109. * length of the message in bytes is reported by the <code>{@link #getLength}</code>
  110. * method.
  111. *
  112. * @return the byte array containing the complete <code>MidiMessage</code> data
  113. */
  114. public byte[] getMessage() {
  115. byte[] returnedArray = new byte[length];
  116. System.arraycopy(data, 0, returnedArray, 0, length);
  117. return returnedArray;
  118. }
  119. /**
  120. * Obtains the status byte for the MIDI message. The status "byte" is
  121. * represented as an integer; see the
  122. * <a href="#integersVsBytes">discussion</a> in the
  123. * <code>MidiMessage</code> class description.
  124. *
  125. * @return the integer representation of this event's status byte
  126. */
  127. public int getStatus() {
  128. if (length > 0) {
  129. return (data[0] & 0xFF);
  130. }
  131. return 0;
  132. }
  133. /**
  134. * Obtains the total length of the MIDI message in bytes. A
  135. * MIDI message consists of one status byte and zero or more
  136. * data bytes. The return value ranges from 1 for system real-time messages,
  137. * to 2 or 3 for channel messages, to any value for meta and system
  138. * exclusive messages.
  139. *
  140. * @return the length of the message in bytes
  141. */
  142. public int getLength() {
  143. return length;
  144. }
  145. /**
  146. * Creates a new object of the same class and with the same contents
  147. * as this object.
  148. * @return a clone of this instance.
  149. */
  150. public abstract Object clone();
  151. }