jdk/src/java.desktop/share/classes/javax/sound/midi/SysexMessage.java
changeset 26037 508779ce6619
parent 26003 d630c97424bd
parent 25859 3317bb8137f4
child 32871 f013b86386e6
equal deleted inserted replaced
25992:e9b05e933ddd 26037:508779ce6619
     1 /*
     1 /*
     2  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
     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.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    24  */
    24  */
    25 
    25 
    26 package javax.sound.midi;
    26 package javax.sound.midi;
    27 
    27 
    28 /**
    28 /**
    29  * A <code>SysexMessage</code> object represents a MIDI system exclusive message.
    29  * A {@code SysexMessage} object represents a MIDI system exclusive message.
    30  * <p>
    30  * <p>
    31  * When a system exclusive message is read from a MIDI file, it always has
    31  * When a system exclusive message is read from a MIDI file, it always has a
    32  * a defined length.  Data from a system exclusive message from a MIDI file
    32  * defined length. Data from a system exclusive message from a MIDI file should
    33  * should be stored in the data array of a <code>SysexMessage</code> as
    33  * be stored in the data array of a {@code SysexMessage} as follows: the system
    34  * follows: the system exclusive message status byte (0xF0 or 0xF7), all
    34  * exclusive message status byte (0xF0 or 0xF7), all message data bytes, and
    35  * message data bytes, and finally the end-of-exclusive flag (0xF7).
    35  * finally the end-of-exclusive flag (0xF7). The length reported by the
    36  * The length reported by the <code>SysexMessage</code> object is therefore
    36  * {@code SysexMessage} object is therefore the length of the system exclusive
    37  * the length of the system exclusive data plus two: one byte for the status
    37  * data plus two: one byte for the status byte and one for the end-of-exclusive
    38  * byte and one for the end-of-exclusive flag.
    38  * flag.
    39  * <p>
    39  * <p>
    40  * As dictated by the Standard MIDI Files specification, two status byte values are legal
    40  * As dictated by the Standard MIDI Files specification, two status byte values
    41  * for a <code>SysexMessage</code> read from a MIDI file:
    41  * are legal for a {@code SysexMessage} read from a MIDI file:
    42  * <ul>
    42  * <ul>
    43  * <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li>
    43  * <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li>
    44  * <li>0xF7: Special System Exclusive message</li>
    44  * <li>0xF7: Special System Exclusive message</li>
    45  * </ul>
    45  * </ul>
    46  * <p>
    46  * When Java Sound is used to handle system exclusive data that is being
    47  * When Java Sound is used to handle system exclusive data that is being received
    47  * received using MIDI wire protocol, it should place the data in one or more
    48  * using MIDI wire protocol, it should place the data in one or more
    48  * {@code SysexMessages}. In this case, the length of the system exclusive data
    49  * <code>SysexMessages</code>.  In this case, the length of the system exclusive data
       
    50  * is not known in advance; the end of the system exclusive data is marked by an
    49  * is not known in advance; the end of the system exclusive data is marked by an
    51  * end-of-exclusive flag (0xF7) in the MIDI wire byte stream.
    50  * end-of-exclusive flag (0xF7) in the MIDI wire byte stream.
    52  * <ul>
    51  * <ul>
    53  * <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li>
    52  * <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li>
    54  * <li>0xF7: End of Exclusive (EOX)</li>
    53  * <li>0xF7: End of Exclusive (EOX)</li>
    55  * </ul>
    54  * </ul>
    56  * The first <code>SysexMessage</code> object containing data for a particular system
    55  * The first {@code SysexMessage} object containing data for a particular system
    57  * exclusive message should have the status value 0xF0.  If this message contains all
    56  * exclusive message should have the status value 0xF0. If this message contains
    58  * the system exclusive data
    57  * all the system exclusive data for the message, it should end with the status
    59  * for the message, it should end with the status byte 0xF7 (EOX).
    58  * byte 0xF7 (EOX). Otherwise, additional system exclusive data should be sent
    60  * Otherwise, additional system exclusive data should be sent in one or more
    59  * in one or more {@code SysexMessages} with a status value of 0xF7. The
    61  * <code>SysexMessages</code> with a status value of 0xF7.  The <code>SysexMessage</code>
    60  * {@code SysexMessage} containing the last of the data for the system exclusive
    62  * containing the last of the data for the system exclusive message should end with the
    61  * message should end with the value 0xF7 (EOX) to mark the end of the system
    63  * value 0xF7 (EOX) to mark the end of the system exclusive message.
    62  * exclusive message.
    64  * <p>
    63  * <p>
    65  * If system exclusive data from <code>SysexMessages</code> objects is being transmitted
    64  * If system exclusive data from {@code SysexMessages} objects is being
    66  * using MIDI wire protocol, only the initial 0xF0 status byte, the system exclusive
    65  * transmitted using MIDI wire protocol, only the initial 0xF0 status byte, the
    67  * data itself, and the final 0xF7 (EOX) byte should be propagated; any 0xF7 status
    66  * system exclusive data itself, and the final 0xF7 (EOX) byte should be
    68  * bytes used to indicate that a <code>SysexMessage</code> contains continuing system
    67  * propagated; any 0xF7 status bytes used to indicate that a
    69  * exclusive data should not be propagated via MIDI wire protocol.
    68  * {@code SysexMessage} contains continuing system exclusive data should not be
       
    69  * propagated via MIDI wire protocol.
    70  *
    70  *
    71  * @author David Rivas
    71  * @author David Rivas
    72  * @author Kara Kytle
    72  * @author Kara Kytle
    73  * @author Florian Bomers
    73  * @author Florian Bomers
    74  */
    74  */
    75 public class SysexMessage extends MidiMessage {
    75 public class SysexMessage extends MidiMessage {
    76 
    76 
    77 
       
    78     // Status byte defines
    77     // Status byte defines
    79 
    78 
    80 
       
    81     /**
    79     /**
    82      * Status byte for System Exclusive message (0xF0, or 240).
    80      * Status byte for System Exclusive message (0xF0, or 240).
       
    81      *
    83      * @see MidiMessage#getStatus
    82      * @see MidiMessage#getStatus
    84      */
    83      */
    85     public static final int SYSTEM_EXCLUSIVE                    = 0xF0; // 240
    84     public static final int SYSTEM_EXCLUSIVE                    = 0xF0; // 240
    86 
    85 
    87 
    86     /**
    88     /**
    87      * Status byte for Special System Exclusive message (0xF7, or 247), which is
    89      * Status byte for Special System Exclusive message (0xF7, or 247), which is used
    88      * used in MIDI files. It has the same value as END_OF_EXCLUSIVE, which is
    90      * in MIDI files.  It has the same value as END_OF_EXCLUSIVE, which
    89      * used in the real-time "MIDI wire" protocol.
    91      * is used in the real-time "MIDI wire" protocol.
    90      *
    92      * @see MidiMessage#getStatus
    91      * @see MidiMessage#getStatus
    93      */
    92      */
    94     public static final int SPECIAL_SYSTEM_EXCLUSIVE    = 0xF7; // 247
    93     public static final int SPECIAL_SYSTEM_EXCLUSIVE    = 0xF7; // 247
    95 
    94 
    96 
    95     /**
    97     // Instance variables
    96      * The data bytes for this system exclusive message. These are initialized
    98 
    97      * to {@code null} and are set explicitly by
    99 
    98      * {@link #setMessage(int, byte[], int, long) setMessage}.
   100     /*
       
   101      * The data bytes for this system exclusive message.  These are
       
   102      * initialized to <code>null</code> and are set explicitly
       
   103      * by {@link #setMessage(int, byte[], int, long) setMessage}.
       
   104      */
    99      */
   105     //protected byte[] data = null;
   100     //protected byte[] data = null;
   106 
   101 
   107 
   102     /**
   108     /**
   103      * Constructs a new {@code SysexMessage}. The contents of the new message
   109      * Constructs a new <code>SysexMessage</code>. The
   104      * are guaranteed to specify a valid MIDI message. Subsequently, you may set
   110      * contents of the new message are guaranteed to specify
   105      * the contents of the message using one of the {@code setMessage} methods.
   111      * a valid MIDI message.  Subsequently, you may set the
   106      *
   112      * contents of the message using one of the <code>setMessage</code>
       
   113      * methods.
       
   114      * @see #setMessage
   107      * @see #setMessage
   115      */
   108      */
   116     public SysexMessage() {
   109     public SysexMessage() {
   117         this(new byte[2]);
   110         this(new byte[2]);
   118         // Default sysex message data: SOX followed by EOX
   111         // Default sysex message data: SOX followed by EOX
   119         data[0] = (byte) (SYSTEM_EXCLUSIVE & 0xFF);
   112         data[0] = (byte) (SYSTEM_EXCLUSIVE & 0xFF);
   120         data[1] = (byte) (ShortMessage.END_OF_EXCLUSIVE & 0xFF);
   113         data[1] = (byte) (ShortMessage.END_OF_EXCLUSIVE & 0xFF);
   121     }
   114     }
   122 
   115 
   123     /**
   116     /**
   124      * Constructs a new {@code SysexMessage} and sets the data for
   117      * Constructs a new {@code SysexMessage} and sets the data for the message.
   125      * the message. The first byte of the data array must be a valid system
   118      * The first byte of the data array must be a valid system exclusive status
   126      * exclusive status byte (0xF0 or 0xF7).
   119      * byte (0xF0 or 0xF7). The contents of the message can be changed by using
   127      * The contents of the message can be changed by using one of
   120      * one of the {@code setMessage} methods.
   128      * the {@code setMessage} methods.
   121      *
   129      *
   122      * @param  data the system exclusive message data including the status byte
   130      * @param data the system exclusive message data including the status byte
   123      * @param  length the length of the valid message data in the array,
   131      * @param length the length of the valid message data in the array,
   124      *         including the status byte; it should be non-negative and less
   132      *     including the status byte; it should be non-negative and less than
   125      *         than or equal to {@code data.length}
   133      *     or equal to {@code data.length}
   126      * @throws InvalidMidiDataException if the parameter values do not specify a
   134      * @throws InvalidMidiDataException if the parameter values
   127      *         valid MIDI meta message.
   135      *     do not specify a valid MIDI meta message.
       
   136      * @see #setMessage(byte[], int)
   128      * @see #setMessage(byte[], int)
   137      * @see #setMessage(int, byte[], int)
   129      * @see #setMessage(int, byte[], int)
   138      * @see #getData()
   130      * @see #getData()
   139      * @since 1.7
   131      * @since 1.7
   140      */
   132      */
   144         setMessage(data, length);
   136         setMessage(data, length);
   145     }
   137     }
   146 
   138 
   147     /**
   139     /**
   148      * Constructs a new {@code SysexMessage} and sets the data for the message.
   140      * Constructs a new {@code SysexMessage} and sets the data for the message.
   149      * The contents of the message can be changed by using one of
   141      * The contents of the message can be changed by using one of the
   150      * the {@code setMessage} methods.
   142      * {@code setMessage} methods.
   151      *
   143      *
   152      * @param status the status byte for the message; it must be a valid system
   144      * @param  status the status byte for the message; it must be a valid system
   153      *     exclusive status byte (0xF0 or 0xF7)
   145      *         exclusive status byte (0xF0 or 0xF7)
   154      * @param data the system exclusive message data (without the status byte)
   146      * @param  data the system exclusive message data (without the status byte)
   155      * @param length the length of the valid message data in the array;
   147      * @param  length the length of the valid message data in the array; it
   156      *     it should be non-negative and less than or equal to
   148      *         should be non-negative and less than or equal to
   157      *     {@code data.length}
   149      *         {@code data.length}
   158      * @throws InvalidMidiDataException if the parameter values
   150      * @throws InvalidMidiDataException if the parameter values do not specify a
   159      *     do not specify a valid MIDI meta message.
   151      *         valid MIDI meta message
   160      * @see #setMessage(byte[], int)
   152      * @see #setMessage(byte[], int)
   161      * @see #setMessage(int, byte[], int)
   153      * @see #setMessage(int, byte[], int)
   162      * @see #getData()
   154      * @see #getData()
   163      * @since 1.7
   155      * @since 1.7
   164      */
   156      */
   166             throws InvalidMidiDataException {
   158             throws InvalidMidiDataException {
   167         super(null);
   159         super(null);
   168         setMessage(status, data, length);
   160         setMessage(status, data, length);
   169     }
   161     }
   170 
   162 
   171 
   163     /**
   172     /**
   164      * Constructs a new {@code SysexMessage}.
   173      * Constructs a new <code>SysexMessage</code>.
   165      *
   174      * @param data an array of bytes containing the complete message.
   166      * @param  data an array of bytes containing the complete message. The
   175      * The message data may be changed using the <code>setMessage</code>
   167      *         message data may be changed using the {@code setMessage} method.
   176      * method.
       
   177      * @see #setMessage
   168      * @see #setMessage
   178      */
   169      */
   179     protected SysexMessage(byte[] data) {
   170     protected SysexMessage(byte[] data) {
   180         super(data);
   171         super(data);
   181     }
   172     }
   182 
   173 
   183 
   174     /**
   184     /**
   175      * Sets the data for the system exclusive message. The first byte of the
   185      * Sets the data for the system exclusive message.   The
   176      * data array must be a valid system exclusive status byte (0xF0 or 0xF7).
   186      * first byte of the data array must be a valid system
   177      *
   187      * exclusive status byte (0xF0 or 0xF7).
   178      * @param  data the system exclusive message data
   188      * @param data the system exclusive message data
   179      * @param  length the length of the valid message data in the array,
   189      * @param length the length of the valid message data in
   180      *         including the status byte
   190      * the array, including the status byte.
       
   191      */
   181      */
   192     public void setMessage(byte[] data, int length) throws InvalidMidiDataException {
   182     public void setMessage(byte[] data, int length) throws InvalidMidiDataException {
   193         int status = (data[0] & 0xFF);
   183         int status = (data[0] & 0xFF);
   194         if ((status != 0xF0) && (status != 0xF7)) {
   184         if ((status != 0xF0) && (status != 0xF7)) {
   195             throw new InvalidMidiDataException("Invalid status byte for sysex message: 0x" + Integer.toHexString(status));
   185             throw new InvalidMidiDataException("Invalid status byte for sysex message: 0x" + Integer.toHexString(status));
   196         }
   186         }
   197         super.setMessage(data, length);
   187         super.setMessage(data, length);
   198     }
   188     }
   199 
   189 
   200 
       
   201     /**
   190     /**
   202      * Sets the data for the system exclusive message.
   191      * Sets the data for the system exclusive message.
   203      * @param status the status byte for the message (0xF0 or 0xF7)
   192      *
   204      * @param data the system exclusive message data
   193      * @param  status the status byte for the message (0xF0 or 0xF7)
   205      * @param length the length of the valid message data in
   194      * @param  data the system exclusive message data
   206      * the array
   195      * @param  length the length of the valid message data in the array
   207      * @throws InvalidMidiDataException if the status byte is invalid for a sysex message
   196      * @throws InvalidMidiDataException if the status byte is invalid for a
       
   197      *         sysex message
   208      */
   198      */
   209     public void setMessage(int status, byte[] data, int length) throws InvalidMidiDataException {
   199     public void setMessage(int status, byte[] data, int length) throws InvalidMidiDataException {
   210         if ( (status != 0xF0) && (status != 0xF7) ) {
   200         if ( (status != 0xF0) && (status != 0xF7) ) {
   211             throw new InvalidMidiDataException("Invalid status byte for sysex message: 0x" + Integer.toHexString(status));
   201             throw new InvalidMidiDataException("Invalid status byte for sysex message: 0x" + Integer.toHexString(status));
   212         }
   202         }
   223         if (length > 0) {
   213         if (length > 0) {
   224             System.arraycopy(data, 0, this.data, 1, length);
   214             System.arraycopy(data, 0, this.data, 1, length);
   225         }
   215         }
   226     }
   216     }
   227 
   217 
   228 
   218     /**
   229     /**
   219      * Obtains a copy of the data for the system exclusive message. The returned
   230      * Obtains a copy of the data for the system exclusive message.
   220      * array of bytes does not include the status byte.
   231      * The returned array of bytes does not include the status byte.
   221      *
   232      * @return array containing the system exclusive message data.
   222      * @return array containing the system exclusive message data
   233      */
   223      */
   234     public byte[] getData() {
   224     public byte[] getData() {
   235         byte[] returnedArray = new byte[length - 1];
   225         byte[] returnedArray = new byte[length - 1];
   236         System.arraycopy(data, 1, returnedArray, 0, (length - 1));
   226         System.arraycopy(data, 1, returnedArray, 0, (length - 1));
   237         return returnedArray;
   227         return returnedArray;
   238     }
   228     }
   239 
   229 
   240 
   230     /**
   241     /**
   231      * Creates a new object of the same class and with the same contents as this
   242      * Creates a new object of the same class and with the same contents
   232      * object.
   243      * as this object.
   233      *
   244      * @return a clone of this instance
   234      * @return a clone of this instance
   245      */
   235      */
   246     public Object clone() {
   236     public Object clone() {
   247         byte[] newData = new byte[length];
   237         byte[] newData = new byte[length];
   248         System.arraycopy(data, 0, newData, 0, newData.length);
   238         System.arraycopy(data, 0, newData, 0, newData.length);