KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > sound > midi > SysexMessage


1 /*
2  * @(#)SysexMessage.java 1.26 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
8 package javax.sound.midi;
9
10 /**
11  * A <code>SysexMessage</code> object represents a MIDI system exclusive message.
12  * <p>
13  * When a system exclusive message is read from a MIDI file, it always has
14  * a defined length. Data from a system exclusive message from a MIDI file
15  * should be stored in the data array of a <code>SysexMessage</code> as
16  * follows: the system exclusive message status byte (0xF0 or 0xF7), all
17  * message data bytes, and finally the end-of-exclusive flag (0xF7).
18  * The length reported by the <code>SysexMessage</code> object is therefore
19  * the length of the system exclusive data plus two: one byte for the status
20  * byte and one for the end-of-exclusive flag.
21  * <p>
22  * As dictated by the Standard MIDI Files specification, two status byte values are legal
23  * for a <code>SysexMessage</code> read from a MIDI file:
24  * <ul>
25  * <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li>
26  * <li>0xF7: Special System Exclusive message</li>
27  * </ul>
28  * <p>
29  * When Java Sound is used to handle system exclusive data that is being received
30  * using MIDI wire protocol, it should place the data in one or more
31  * <code>SysexMessages</code>. In this case, the length of the system exclusive data
32  * is not known in advance; the end of the system exclusive data is marked by an
33  * end-of-exclusive flag (0xF7) in the MIDI wire byte stream.
34  * <ul>
35  * <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li>
36  * <li>0xF7: End of Exclusive (EOX)</li>
37  * </ul>
38  * The first <code>SysexMessage</code> object containing data for a particular system
39  * exclusive message should have the status value 0xF0. If this message contains all
40  * the system exclusive data
41  * for the message, it should end with the status byte 0xF7 (EOX).
42  * Otherwise, additional system exclusive data should be sent in one or more
43  * <code>SysexMessages</code> with a status value of 0xF7. The <code>SysexMessage</code>
44  * containing the last of the data for the system exclusive message should end with the
45  * value 0xF7 (EOX) to mark the end of the system exclusive message.
46  * <p>
47  * If system exclusive data from <code>SysexMessages</code> objects is being transmitted
48  * using MIDI wire protocol, only the initial 0xF0 status byte, the system exclusive
49  * data itself, and the final 0xF7 (EOX) byte should be propagated; any 0xF7 status
50  * bytes used to indicate that a <code>SysexMessage</code> contains continuing system
51  * exclusive data should not be propagated via MIDI wire protocol.
52  *
53  * @version 1.26, 03/12/19
54  * @author David Rivas
55  * @author Kara Kytle
56  * @author Florian Bomers
57  */

58 public class SysexMessage extends MidiMessage JavaDoc {
59
60
61     // Status byte defines
62

63
64     /**
65      * Status byte for System Exclusive message (0xF0, or 240).
66      * @see MidiMessage#getStatus
67      */

68     public static final int SYSTEM_EXCLUSIVE = 0xF0; // 240
69

70
71     /**
72      * Status byte for Special System Exclusive message (0xF7, or 247), which is used
73      * in MIDI files. It has the same value as END_OF_EXCLUSIVE, which
74      * is used in the real-time "MIDI wire" protocol.
75      * @see MidiMessage#getStatus
76      */

77     public static final int SPECIAL_SYSTEM_EXCLUSIVE = 0xF7; // 247
78

79
80     // Instance variables
81

82
83     /*
84      * The data bytes for this system exclusive message. These are
85      * initialized to <code>null</code> and are set explicitly
86      * by {@link #setMessage(int, byte[], int, long) setMessage}.
87      */

88     //protected byte[] data = null;
89

90
91     /**
92      * Constructs a new <code>SysexMessage</code>. The
93      * contents of the new message are guaranteed to specify
94      * a valid MIDI message. Subsequently, you may set the
95      * contents of the message using one of the <code>setMessage</code>
96      * methods.
97      * @see #setMessage
98      */

99     public SysexMessage() {
100     this(new byte[2]);
101     // Default sysex message data: SOX followed by EOX
102
data[0] = (byte) (SYSTEM_EXCLUSIVE & 0xFF);
103     data[1] = (byte) (ShortMessage.END_OF_EXCLUSIVE & 0xFF);
104     }
105
106
107     /**
108      * Constructs a new <code>SysexMessage</code>.
109      * @param data an array of bytes containing the complete message.
110      * The message data may be changed using the <code>setMessage</code>
111      * method.
112      * @see #setMessage
113      */

114     protected SysexMessage(byte[] data) {
115     super(data);
116     }
117
118
119     /**
120      * Sets the data for the system exclusive message. The
121      * first byte of the data array must be a valid system
122      * exclusive status byte (0xF0 or 0xF7).
123      * @param data the system exclusive message data
124      * @param length the length of the valid message data in
125      * the array, including the status byte.
126      */

127     public void setMessage(byte[] data, int length) throws InvalidMidiDataException JavaDoc {
128     int status = (data[0] & 0xFF);
129     if ((status != 0xF0) && (status != 0xF7)) {
130         throw new InvalidMidiDataException JavaDoc("Invalid status byte for sysex message: 0x" + Integer.toHexString(status));
131     }
132     super.setMessage(data, length);
133     }
134
135
136     /**
137      * Sets the data for the system exclusive message.
138      * @param status the status byte for the message (0xF0 or 0xF7)
139      * @param data the system exclusive message data
140      * @param length the length of the valid message data in
141      * the array
142      */

143     public void setMessage(int status, byte[] data, int length) throws InvalidMidiDataException JavaDoc {
144     if ( (status != 0xF0) && (status != 0xF7) ) {
145         throw new InvalidMidiDataException JavaDoc("Invalid status byte for sysex message: 0x" + Integer.toHexString(status));
146     }
147     if (length < 0 || length > data.length) {
148         throw new IndexOutOfBoundsException JavaDoc("length out of bounds: "+length);
149     }
150     this.length = length + 1;
151
152     if (this.data==null || this.data.length < this.length) {
153         this.data = new byte[this.length];
154     }
155
156     this.data[0] = (byte) (status & 0xFF);
157     if (length > 0) {
158         System.arraycopy(data, 0, this.data, 1, length);
159     }
160     }
161
162
163     /**
164      * Obtains a copy of the data for the system exclusive message.
165      * The returned array of bytes does not include the status byte.
166      * @return array containing the system exclusive message data.
167      */

168     public byte[] getData() {
169     byte[] returnedArray = new byte[length - 1];
170     System.arraycopy(data, 1, returnedArray, 0, (length - 1));
171     return returnedArray;
172     }
173
174
175     /**
176      * Creates a new object of the same class and with the same contents
177      * as this object.
178      * @return a clone of this instance
179      */

180     public Object JavaDoc clone() {
181     byte[] newData = new byte[length];
182     System.arraycopy(data, 0, newData, 0, newData.length);
183     SysexMessage JavaDoc event = new SysexMessage JavaDoc(newData);
184     return event;
185     }
186 }
187
Popular Tags