Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/sound/midi/SysexMessage.java
38830 views
/*1* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.sound.midi;2627/**28* A <code>SysexMessage</code> object represents a MIDI system exclusive message.29* <p>30* When a system exclusive message is read from a MIDI file, it always has31* a defined length. Data from a system exclusive message from a MIDI file32* should be stored in the data array of a <code>SysexMessage</code> as33* follows: the system exclusive message status byte (0xF0 or 0xF7), all34* message data bytes, and finally the end-of-exclusive flag (0xF7).35* The length reported by the <code>SysexMessage</code> object is therefore36* the length of the system exclusive data plus two: one byte for the status37* byte and one for the end-of-exclusive flag.38* <p>39* As dictated by the Standard MIDI Files specification, two status byte values are legal40* for a <code>SysexMessage</code> read from a MIDI file:41* <ul>42* <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li>43* <li>0xF7: Special System Exclusive message</li>44* </ul>45* <p>46* When Java Sound is used to handle system exclusive data that is being received47* using MIDI wire protocol, it should place the data in one or more48* <code>SysexMessages</code>. In this case, the length of the system exclusive data49* is not known in advance; the end of the system exclusive data is marked by an50* end-of-exclusive flag (0xF7) in the MIDI wire byte stream.51* <ul>52* <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li>53* <li>0xF7: End of Exclusive (EOX)</li>54* </ul>55* The first <code>SysexMessage</code> object containing data for a particular system56* exclusive message should have the status value 0xF0. If this message contains all57* the system exclusive data58* for the message, it should end with the status byte 0xF7 (EOX).59* Otherwise, additional system exclusive data should be sent in one or more60* <code>SysexMessages</code> with a status value of 0xF7. The <code>SysexMessage</code>61* containing the last of the data for the system exclusive message should end with the62* value 0xF7 (EOX) to mark the end of the system exclusive message.63* <p>64* If system exclusive data from <code>SysexMessages</code> objects is being transmitted65* using MIDI wire protocol, only the initial 0xF0 status byte, the system exclusive66* data itself, and the final 0xF7 (EOX) byte should be propagated; any 0xF7 status67* bytes used to indicate that a <code>SysexMessage</code> contains continuing system68* exclusive data should not be propagated via MIDI wire protocol.69*70* @author David Rivas71* @author Kara Kytle72* @author Florian Bomers73*/74public class SysexMessage extends MidiMessage {757677// Status byte defines787980/**81* Status byte for System Exclusive message (0xF0, or 240).82* @see MidiMessage#getStatus83*/84public static final int SYSTEM_EXCLUSIVE = 0xF0; // 240858687/**88* Status byte for Special System Exclusive message (0xF7, or 247), which is used89* in MIDI files. It has the same value as END_OF_EXCLUSIVE, which90* is used in the real-time "MIDI wire" protocol.91* @see MidiMessage#getStatus92*/93public static final int SPECIAL_SYSTEM_EXCLUSIVE = 0xF7; // 247949596// Instance variables979899/*100* The data bytes for this system exclusive message. These are101* initialized to <code>null</code> and are set explicitly102* by {@link #setMessage(int, byte[], int, long) setMessage}.103*/104//protected byte[] data = null;105106107/**108* Constructs a new <code>SysexMessage</code>. The109* contents of the new message are guaranteed to specify110* a valid MIDI message. Subsequently, you may set the111* contents of the message using one of the <code>setMessage</code>112* methods.113* @see #setMessage114*/115public SysexMessage() {116this(new byte[2]);117// Default sysex message data: SOX followed by EOX118data[0] = (byte) (SYSTEM_EXCLUSIVE & 0xFF);119data[1] = (byte) (ShortMessage.END_OF_EXCLUSIVE & 0xFF);120}121122/**123* Constructs a new {@code SysexMessage} and sets the data for124* the message. The first byte of the data array must be a valid system125* exclusive status byte (0xF0 or 0xF7).126* The contents of the message can be changed by using one of127* the {@code setMessage} methods.128*129* @param data the system exclusive message data including the status byte130* @param length the length of the valid message data in the array,131* including the status byte; it should be non-negative and less than132* or equal to {@code data.length}133* @throws InvalidMidiDataException if the parameter values134* do not specify a valid MIDI meta message.135* @see #setMessage(byte[], int)136* @see #setMessage(int, byte[], int)137* @see #getData()138* @since 1.7139*/140public SysexMessage(byte[] data, int length)141throws InvalidMidiDataException {142super(null);143setMessage(data, length);144}145146/**147* Constructs a new {@code SysexMessage} and sets the data for the message.148* The contents of the message can be changed by using one of149* the {@code setMessage} methods.150*151* @param status the status byte for the message; it must be a valid system152* exclusive status byte (0xF0 or 0xF7)153* @param data the system exclusive message data (without the status byte)154* @param length the length of the valid message data in the array;155* it should be non-negative and less than or equal to156* {@code data.length}157* @throws InvalidMidiDataException if the parameter values158* do not specify a valid MIDI meta message.159* @see #setMessage(byte[], int)160* @see #setMessage(int, byte[], int)161* @see #getData()162* @since 1.7163*/164public SysexMessage(int status, byte[] data, int length)165throws InvalidMidiDataException {166super(null);167setMessage(status, data, length);168}169170171/**172* Constructs a new <code>SysexMessage</code>.173* @param data an array of bytes containing the complete message.174* The message data may be changed using the <code>setMessage</code>175* method.176* @see #setMessage177*/178protected SysexMessage(byte[] data) {179super(data);180}181182183/**184* Sets the data for the system exclusive message. The185* first byte of the data array must be a valid system186* exclusive status byte (0xF0 or 0xF7).187* @param data the system exclusive message data188* @param length the length of the valid message data in189* the array, including the status byte.190*/191public void setMessage(byte[] data, int length) throws InvalidMidiDataException {192int status = (data[0] & 0xFF);193if ((status != 0xF0) && (status != 0xF7)) {194throw new InvalidMidiDataException("Invalid status byte for sysex message: 0x" + Integer.toHexString(status));195}196super.setMessage(data, length);197}198199200/**201* Sets the data for the system exclusive message.202* @param status the status byte for the message (0xF0 or 0xF7)203* @param data the system exclusive message data204* @param length the length of the valid message data in205* the array206* @throws InvalidMidiDataException if the status byte is invalid for a sysex message207*/208public void setMessage(int status, byte[] data, int length) throws InvalidMidiDataException {209if ( (status != 0xF0) && (status != 0xF7) ) {210throw new InvalidMidiDataException("Invalid status byte for sysex message: 0x" + Integer.toHexString(status));211}212if (length < 0 || length > data.length) {213throw new IndexOutOfBoundsException("length out of bounds: "+length);214}215this.length = length + 1;216217if (this.data==null || this.data.length < this.length) {218this.data = new byte[this.length];219}220221this.data[0] = (byte) (status & 0xFF);222if (length > 0) {223System.arraycopy(data, 0, this.data, 1, length);224}225}226227228/**229* Obtains a copy of the data for the system exclusive message.230* The returned array of bytes does not include the status byte.231* @return array containing the system exclusive message data.232*/233public byte[] getData() {234byte[] returnedArray = new byte[length - 1];235System.arraycopy(data, 1, returnedArray, 0, (length - 1));236return returnedArray;237}238239240/**241* Creates a new object of the same class and with the same contents242* as this object.243* @return a clone of this instance244*/245public Object clone() {246byte[] newData = new byte[length];247System.arraycopy(data, 0, newData, 0, newData.length);248SysexMessage event = new SysexMessage(newData);249return event;250}251}252253254