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