Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/sound/midi/ShortMessage.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>ShortMessage</code> contains a MIDI message that has at most29* two data bytes following its status byte. The types of MIDI message30* that satisfy this criterion are channel voice, channel mode, system common,31* and system real-time--in other words, everything except system exclusive32* and meta-events. The <code>ShortMessage</code> class provides methods33* for getting and setting the contents of the MIDI message.34* <p>35* A number of <code>ShortMessage</code> methods have integer parameters by which36* you specify a MIDI status or data byte. If you know the numeric value, you37* can express it directly. For system common and system real-time messages,38* you can often use the corresponding fields of <code>ShortMessage</code>, such as39* {@link #SYSTEM_RESET SYSTEM_RESET}. For channel messages,40* the upper four bits of the status byte are specified by a command value and41* the lower four bits are specified by a MIDI channel number. To42* convert incoming MIDI data bytes that are in the form of Java's signed bytes,43* you can use the <A HREF="MidiMessage.html#integersVsBytes">conversion code</A>44* given in the <code>{@link MidiMessage}</code> class description.45*46* @see SysexMessage47* @see MetaMessage48*49* @author David Rivas50* @author Kara Kytle51* @author Florian Bomers52*/5354public class ShortMessage extends MidiMessage {555657// Status byte defines585960// System common messages6162/**63* Status byte for MIDI Time Code Quarter Frame message (0xF1, or 241).64* @see MidiMessage#getStatus65*/66public static final int MIDI_TIME_CODE = 0xF1; // 2416768/**69* Status byte for Song Position Pointer message (0xF2, or 242).70* @see MidiMessage#getStatus71*/72public static final int SONG_POSITION_POINTER = 0xF2; // 2427374/**75* Status byte for MIDI Song Select message (0xF3, or 243).76* @see MidiMessage#getStatus77*/78public static final int SONG_SELECT = 0xF3; // 2437980/**81* Status byte for Tune Request message (0xF6, or 246).82* @see MidiMessage#getStatus83*/84public static final int TUNE_REQUEST = 0xF6; // 2468586/**87* Status byte for End of System Exclusive message (0xF7, or 247).88* @see MidiMessage#getStatus89*/90public static final int END_OF_EXCLUSIVE = 0xF7; // 247919293// System real-time messages9495/**96* Status byte for Timing Clock message (0xF8, or 248).97* @see MidiMessage#getStatus98*/99public static final int TIMING_CLOCK = 0xF8; // 248100101/**102* Status byte for Start message (0xFA, or 250).103* @see MidiMessage#getStatus104*/105public static final int START = 0xFA; // 250106107/**108* Status byte for Continue message (0xFB, or 251).109* @see MidiMessage#getStatus110*/111public static final int CONTINUE = 0xFB; // 251112113/**114* Status byte for Stop message (0xFC, or 252).115* @see MidiMessage#getStatus116*/117public static final int STOP = 0xFC; //252118119/**120* Status byte for Active Sensing message (0xFE, or 254).121* @see MidiMessage#getStatus122*/123public static final int ACTIVE_SENSING = 0xFE; // 254124125/**126* Status byte for System Reset message (0xFF, or 255).127* @see MidiMessage#getStatus128*/129public static final int SYSTEM_RESET = 0xFF; // 255130131132// Channel voice message upper nibble defines133134/**135* Command value for Note Off message (0x80, or 128)136*/137public static final int NOTE_OFF = 0x80; // 128138139/**140* Command value for Note On message (0x90, or 144)141*/142public static final int NOTE_ON = 0x90; // 144143144/**145* Command value for Polyphonic Key Pressure (Aftertouch) message (0xA0, or 160)146*/147public static final int POLY_PRESSURE = 0xA0; // 160148149/**150* Command value for Control Change message (0xB0, or 176)151*/152public static final int CONTROL_CHANGE = 0xB0; // 176153154/**155* Command value for Program Change message (0xC0, or 192)156*/157public static final int PROGRAM_CHANGE = 0xC0; // 192158159/**160* Command value for Channel Pressure (Aftertouch) message (0xD0, or 208)161*/162public static final int CHANNEL_PRESSURE = 0xD0; // 208163164/**165* Command value for Pitch Bend message (0xE0, or 224)166*/167public static final int PITCH_BEND = 0xE0; // 224168169170// Instance variables171172/**173* Constructs a new <code>ShortMessage</code>. The174* contents of the new message are guaranteed to specify175* a valid MIDI message. Subsequently, you may set the176* contents of the message using one of the <code>setMessage</code>177* methods.178* @see #setMessage179*/180public ShortMessage() {181this(new byte[3]);182// Default message data: NOTE_ON on Channel 0 with max volume183data[0] = (byte) (NOTE_ON & 0xFF);184data[1] = (byte) 64;185data[2] = (byte) 127;186length = 3;187}188189/**190* Constructs a new {@code ShortMessage} which represents a MIDI191* message that takes no data bytes.192* The contents of the message can be changed by using one of193* the {@code setMessage} methods.194*195* @param status the MIDI status byte196* @throws InvalidMidiDataException if {@code status} does not specify197* a valid MIDI status byte for a message that requires no data bytes198* @see #setMessage(int)199* @see #setMessage(int, int, int)200* @see #setMessage(int, int, int, int)201* @see #getStatus()202* @since 1.7203*/204public ShortMessage(int status) throws InvalidMidiDataException {205super(null);206setMessage(status); // can throw InvalidMidiDataException207}208209/**210* Constructs a new {@code ShortMessage} which represents a MIDI message211* that takes up to two data bytes. If the message only takes one data byte,212* the second data byte is ignored. If the message does not take213* any data bytes, both data bytes are ignored.214* The contents of the message can be changed by using one of215* the {@code setMessage} methods.216*217* @param status the MIDI status byte218* @param data1 the first data byte219* @param data2 the second data byte220* @throws InvalidMidiDataException if the status byte or all data bytes221* belonging to the message do not specify a valid MIDI message222* @see #setMessage(int)223* @see #setMessage(int, int, int)224* @see #setMessage(int, int, int, int)225* @see #getStatus()226* @see #getData1()227* @see #getData2()228* @since 1.7229*/230public ShortMessage(int status, int data1, int data2)231throws InvalidMidiDataException {232super(null);233setMessage(status, data1, data2); // can throw InvalidMidiDataException234}235236/**237* Constructs a new {@code ShortMessage} which represents a channel238* MIDI message that takes up to two data bytes. If the message only takes239* one data byte, the second data byte is ignored. If the message does not240* take any data bytes, both data bytes are ignored.241* The contents of the message can be changed by using one of242* the {@code setMessage} methods.243*244* @param command the MIDI command represented by this message245* @param channel the channel associated with the message246* @param data1 the first data byte247* @param data2 the second data byte248* @throws InvalidMidiDataException if the command value, channel value249* or all data bytes belonging to the message do not specify250* a valid MIDI message251* @see #setMessage(int)252* @see #setMessage(int, int, int)253* @see #setMessage(int, int, int, int)254* @see #getCommand()255* @see #getChannel()256* @see #getData1()257* @see #getData2()258* @since 1.7259*/260public ShortMessage(int command, int channel, int data1, int data2)261throws InvalidMidiDataException {262super(null);263setMessage(command, channel, data1, data2);264}265266267/**268* Constructs a new <code>ShortMessage</code>.269* @param data an array of bytes containing the complete message.270* The message data may be changed using the <code>setMessage</code>271* method.272* @see #setMessage273*/274// $$fb this should throw an Exception in case of an illegal message!275protected ShortMessage(byte[] data) {276// $$fb this may set an invalid message.277// Can't correct without compromising compatibility278super(data);279}280281282/**283* Sets the parameters for a MIDI message that takes no data bytes.284* @param status the MIDI status byte285* @throws InvalidMidiDataException if <code>status</code> does not286* specify a valid MIDI status byte for a message that requires no data bytes.287* @see #setMessage(int, int, int)288* @see #setMessage(int, int, int, int)289*/290public void setMessage(int status) throws InvalidMidiDataException {291// check for valid values292int dataLength = getDataLength(status); // can throw InvalidMidiDataException293if (dataLength != 0) {294throw new InvalidMidiDataException("Status byte; " + status + " requires " + dataLength + " data bytes");295}296setMessage(status, 0, 0);297}298299300/**301* Sets the parameters for a MIDI message that takes one or two data302* bytes. If the message takes only one data byte, the second data303* byte is ignored; if the message does not take any data bytes, both304* data bytes are ignored.305*306* @param status the MIDI status byte307* @param data1 the first data byte308* @param data2 the second data byte309* @throws InvalidMidiDataException if the310* the status byte, or all data bytes belonging to the message, do311* not specify a valid MIDI message.312* @see #setMessage(int, int, int, int)313* @see #setMessage(int)314*/315public void setMessage(int status, int data1, int data2) throws InvalidMidiDataException {316// check for valid values317int dataLength = getDataLength(status); // can throw InvalidMidiDataException318if (dataLength > 0) {319if (data1 < 0 || data1 > 127) {320throw new InvalidMidiDataException("data1 out of range: " + data1);321}322if (dataLength > 1) {323if (data2 < 0 || data2 > 127) {324throw new InvalidMidiDataException("data2 out of range: " + data2);325}326}327}328329330// set the length331length = dataLength + 1;332// re-allocate array if ShortMessage(byte[]) constructor gave array with fewer elements333if (data == null || data.length < length) {334data = new byte[3];335}336337// set the data338data[0] = (byte) (status & 0xFF);339if (length > 1) {340data[1] = (byte) (data1 & 0xFF);341if (length > 2) {342data[2] = (byte) (data2 & 0xFF);343}344}345}346347348/**349* Sets the short message parameters for a channel message350* which takes up to two data bytes. If the message only351* takes one data byte, the second data byte is ignored; if352* the message does not take any data bytes, both data bytes353* are ignored.354*355* @param command the MIDI command represented by this message356* @param channel the channel associated with the message357* @param data1 the first data byte358* @param data2 the second data byte359* @throws InvalidMidiDataException if the360* status byte or all data bytes belonging to the message, do361* not specify a valid MIDI message362*363* @see #setMessage(int, int, int)364* @see #setMessage(int)365* @see #getCommand366* @see #getChannel367* @see #getData1368* @see #getData2369*/370public void setMessage(int command, int channel, int data1, int data2) throws InvalidMidiDataException {371// check for valid values372if (command >= 0xF0 || command < 0x80) {373throw new InvalidMidiDataException("command out of range: 0x" + Integer.toHexString(command));374}375if ((channel & 0xFFFFFFF0) != 0) { // <=> (channel<0 || channel>15)376throw new InvalidMidiDataException("channel out of range: " + channel);377}378setMessage((command & 0xF0) | (channel & 0x0F), data1, data2);379}380381382/**383* Obtains the MIDI channel associated with this event. This method384* assumes that the event is a MIDI channel message; if not, the return385* value will not be meaningful.386* @return MIDI channel associated with the message.387* @see #setMessage(int, int, int, int)388*/389public int getChannel() {390// this returns 0 if an invalid message is set391return (getStatus() & 0x0F);392}393394395/**396* Obtains the MIDI command associated with this event. This method397* assumes that the event is a MIDI channel message; if not, the return398* value will not be meaningful.399* @return the MIDI command associated with this event400* @see #setMessage(int, int, int, int)401*/402public int getCommand() {403// this returns 0 if an invalid message is set404return (getStatus() & 0xF0);405}406407408/**409* Obtains the first data byte in the message.410* @return the value of the <code>data1</code> field411* @see #setMessage(int, int, int)412*/413public int getData1() {414if (length > 1) {415return (data[1] & 0xFF);416}417return 0;418}419420421/**422* Obtains the second data byte in the message.423* @return the value of the <code>data2</code> field424* @see #setMessage(int, int, int)425*/426public int getData2() {427if (length > 2) {428return (data[2] & 0xFF);429}430return 0;431}432433434/**435* Creates a new object of the same class and with the same contents436* as this object.437* @return a clone of this instance.438*/439public Object clone() {440byte[] newData = new byte[length];441System.arraycopy(data, 0, newData, 0, newData.length);442443ShortMessage msg = new ShortMessage(newData);444return msg;445}446447448/**449* Retrieves the number of data bytes associated with a particular450* status byte value.451* @param status status byte value, which must represent a short MIDI message452* @return data length in bytes (0, 1, or 2)453* @throws InvalidMidiDataException if the454* <code>status</code> argument does not represent the status byte for any455* short message456*/457protected final int getDataLength(int status) throws InvalidMidiDataException {458// system common and system real-time messages459switch(status) {460case 0xF6: // Tune Request461case 0xF7: // EOX462// System real-time messages463case 0xF8: // Timing Clock464case 0xF9: // Undefined465case 0xFA: // Start466case 0xFB: // Continue467case 0xFC: // Stop468case 0xFD: // Undefined469case 0xFE: // Active Sensing470case 0xFF: // System Reset471return 0;472case 0xF1: // MTC Quarter Frame473case 0xF3: // Song Select474return 1;475case 0xF2: // Song Position Pointer476return 2;477default:478}479480// channel voice and mode messages481switch(status & 0xF0) {482case 0x80:483case 0x90:484case 0xA0:485case 0xB0:486case 0xE0:487return 2;488case 0xC0:489case 0xD0:490return 1;491default:492throw new InvalidMidiDataException("Invalid status byte: " + status);493}494}495}496497498