diff options
Diffstat (limited to 'libjava/classpath/javax/sound/midi/MetaMessage.java')
-rw-r--r-- | libjava/classpath/javax/sound/midi/MetaMessage.java | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/libjava/classpath/javax/sound/midi/MetaMessage.java b/libjava/classpath/javax/sound/midi/MetaMessage.java new file mode 100644 index 00000000000..2ca93accd77 --- /dev/null +++ b/libjava/classpath/javax/sound/midi/MetaMessage.java @@ -0,0 +1,176 @@ +/* MetaMessage.java -- A meta message for MIDI files. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.sound.midi; + +/** + * A system exclusive MIDI message. + * + * @author Anthony Green (green@redhat.com) + * @since 1.3 + * + */ +public class MetaMessage extends MidiMessage +{ + /** + * The META status code. Only valid for MIDI files, not the wire protocol. + */ + public static final int META = 0xFF; + + // The length of the variable length data length encoding. + private int lengthLength = 0; + + /** + * Create a default valid meta message. + * + * The official specs don't specify what message is to be + * created. For now, we create a zero length meta message + * with a type code of 0. + */ + public MetaMessage() + { + super(new byte[4]); + data[0] = (byte) META; + data[1] = (byte) 0; // Type + data[2] = (byte) 1; // Length length + data[3] = (byte) 0; // Length + lengthLength = 1; + } + + /** + * Create a MetaMessage object. + * @param data a complete system exclusive message + */ + public MetaMessage(byte[] data) + { + super(data); + int index = 2; + lengthLength = 1; + while ((data[index++] & 0x80) > 0) + lengthLength++; + } + + /** + * Set the meta message. + * + * @param type the meta type byte (< 128) + * @param data the message data + * @param length the length of the message data + * @throws InvalidMidiDataException if this message is invalid + */ + public void setMessage(int type, byte[] data, int length) + throws InvalidMidiDataException + { + if (type > 127) + throw new InvalidMidiDataException("Meta type 0x" + + Integer.toHexString(type) + + " must be less than 128"); + + // For a nice description of how variable length values are handled, + // see http://www.borg.com/~jglatt/tech/midifile.htm + + // First compute the length of the length value + lengthLength = 0; + int lengthValue = length; + do { + lengthValue = lengthValue >> 7; + lengthLength++; + } while (lengthValue > 0); + + // Now allocate our data array + this.length = 2 + lengthLength + length; + this.data = new byte[this.length]; + this.data[0] = (byte) META; + this.data[1] = (byte) type; + + // Now compute the length representation + long buffer = length & 0x7F; + while ((length >>= 7) > 0) + { + buffer <<= 8; + buffer |= ((length & 0x7F) | 0x80); + } + + // Now store the variable length length value + int index = 2; + do + { + this.data[index++] = (byte) (buffer & 0xFF); + if ((buffer & 0x80) == 0) + break; + buffer >>= 8; + } while (true); + + // Now copy the real data. + System.arraycopy(data, 0, this.data, index, length); + } + + /** + * Get the meta message type. + * + * @return the meta message type + */ + public int getType() + { + return data[1]; + } + + /** + * Get the data for this message, not including the status, + * type, or length information. + * + * @return the message data, not including status, type or lenght info + */ + public byte[] getData() + { + int dataLength = length - 2 - lengthLength; + byte[] result = new byte[dataLength]; + System.arraycopy(data, 2 + lengthLength, result, 0, dataLength); + return result; + } + + /* Create a deep-copy clone of this object. + * @see java.lang.Object#clone() + */ + public Object clone() + { + byte message[] = new byte[length]; + System.arraycopy(data, 0, message, 0, length); + return new MetaMessage(message); + } +} |