Index: modules/sound/src/main/java/javax/sound/midi/ShortMessage.java =================================================================== --- modules/sound/src/main/java/javax/sound/midi/ShortMessage.java (revision 425597) +++ modules/sound/src/main/java/javax/sound/midi/ShortMessage.java (working copy) @@ -67,36 +67,11 @@ private int command; public ShortMessage() { - super(new byte[] { -112, 64, 127 }); - data1 = 64; - data2 = 127; - channel = 0; - command = 144; + super(new byte[] {-112, 64, 127}); } protected ShortMessage(byte[] data) { super(data); - if ((data == null) || (data.length == 0)) { - data1 = 0; - data2 = 0; - channel = 0; - command = 0; - } else if (data.length >= 3) { - data1 = (int) (data[1] & 0xFF); - data2 = (int) (data[2] & 0xFF); - channel = ((int) (data[0] & 0xFF)) % 16; - command = ((int) (data[0] & 0xFF)) - channel; - } else if (data.length == 2) { - data1 = (int) (data[1] & 0xFF); - data2 = 0; - channel = ((int) (data[0] & 0xFF)) % 16; - command = ((int) (data[0] & 0xFF)) - channel; - } else { - data1 = 0; - data2 = 0; - channel = ((int) (data[0] & 0xFF)) % 16; - command = ((int) (data[0] & 0xFF)) - channel; - } } public Object clone() { @@ -104,19 +79,45 @@ } public int getChannel() { - return channel; + /** + * channel change from 0 up to 15 + */ + if ((data == null) || (data.length == 0)) { + return 0; + } else { + return ((int) (data[0] & 0xFF)) % 16; + } } public int getCommand() { - return command; + /** + * command should be divisible by 16 without rest + */ + if ((data == null) || (data.length == 0)) { + return 0; + } else { + return ((int) (data[0] & 0xFF)) - getChannel(); + } } public int getData1() { - return data1; + if ((data == null) || (data.length == 0)) { + return 0; + } else if (data.length < 2) { + return 0; + } else { + return (int) (data[1] & 0xFF); + } } public int getData2() { - return data2; + if ((data == null) || (data.length == 0)) { + return 0; + } else if (data.length < 3) { + return 0; + } else { + return (int) (data[2] & 0xFF); + } } protected final int getDataLength(int status) @@ -132,10 +133,13 @@ * value of status from 496 up to 511, from 752 up to 767 and so on, * i.e. on the last 16 number of 256-lap. And now differences in the * first lap. This method don't throw out exception with value of status - * from 240 up to 255. It has next behavior: - value of status equals - * 240 -- throw out exception; - 241 -- return 1; - 242 -- return 2; - - * 243 -- return 1; - from 244 up to 245 -- throw out exception; - from - * 246 up to 255 -- return 0; + * from 240 up to 255. It has next behavior: + * - value of status equals 240 -- throw out exception; + * - 241 -- return 1; + * - 242 -- return 2; + * - 243 -- return 1; + * - from 244 up to 245 -- throw out exception; + * - from 246 up to 255 -- return 0; */ if (status < 0) { throw new InvalidMidiDataException("Invalid status byte: " + status); @@ -177,14 +181,7 @@ if ((status < 246) || (status > 255)) { throw new InvalidMidiDataException("Invalid status byte: " + status); } - super.setMessage(new byte[] { (byte) status }, 1); - /** - * channel change from 0 up to 15, and channel + command == status - */ - data1 = 0; - data2 = 0; - channel = status % 16; - command = status - channel; + super.setMessage(new byte[] {(byte) status}, 1); } public void setMessage(int status, int data1, int data2) @@ -197,20 +194,10 @@ * return 0 when I modify status byte from 246 up to 255, and so I think * it's true. */ - /** - * value of variable status is more or equals 246 and less or equals 255 - */ if ((status < 246) || (status > 255)) { throw new InvalidMidiDataException("Invalid status byte: " + status); } - super.setMessage(new byte[] { (byte) status }, 1); - /** - * channel change from 0 up to 15, and channel + command == status - */ - this.data1 = 0; - this.data2 = 0; - channel = status % 16; - command = status - channel; + super.setMessage(new byte[] {(byte) status}, 1); } public void setMessage(int command, int channel, int data1, int data2) @@ -225,15 +212,13 @@ * when this exception throw out, the value of variable command * should be the hexadecimal number */ - throw new InvalidMidiDataException("command out of range: " - + command); + throw new InvalidMidiDataException("command out of range: " + command); } /** * value of variable channel is more or equals 0 and less or equals 15 */ if ((channel < 0) || (channel > 15)) { - throw new InvalidMidiDataException("channel out of range: " - + channel); + throw new InvalidMidiDataException("channel out of range: " + channel); } /** * value of data1 and data2 is more or equals 0 and less or equals 127, @@ -241,30 +226,19 @@ * data, data2, is unused, because getDataLength(int) return 1 in this * case, and in other cases it return 2 */ - if ((data1 < 0) || (data1 > 127)) { + if ((getDataLength(command) >= 1) && ((data1 < 0) || (data1 > 127))) { throw new InvalidMidiDataException("data1 out of range: " + data1); } if ((getDataLength(command) == 2) && ((data2 < 0) || (data2 > 127))) { throw new InvalidMidiDataException("data2 out of range: " + data2); } - /** - * channel change from 0 up to 15, and channel + command == status - */ - this.command = command - (command % 16); - this.channel = channel; - this.data1 = data1; - /** - * status in this case equals getCommand() + getChannel() - */ + int tcom = command - (command % 16); if (getDataLength(command) == 1) { - super.setMessage(new byte[] { (byte) (this.command + this.channel), - (byte) data1 }, 2); - this.data2 = 0; + super.setMessage(new byte[] {(byte) (tcom + channel), (byte) data1}, 2); } else { - super.setMessage(new byte[] { (byte) (this.command + this.channel), - (byte) data1, (byte) data2 }, 3); - this.data2 = data2; + super.setMessage(new byte[] {(byte) (tcom + channel), (byte) data1, + (byte) data2}, 3); } } Index: modules/sound/src/main/java/javax/sound/midi/MidiMessage.java =================================================================== --- modules/sound/src/main/java/javax/sound/midi/MidiMessage.java (revision 425597) +++ modules/sound/src/main/java/javax/sound/midi/MidiMessage.java (working copy) @@ -17,19 +17,17 @@ package javax.sound.midi; public abstract class MidiMessage implements Cloneable { - private int status; protected byte[] data; protected int length; protected MidiMessage(byte[] data) { - if (data == null || data.length == 0) { - data = null; + if (data == null) { + length = 0; } else { length = data.length; - status = (int) (data[0] & 0xFF); - this.data = data.clone(); + this.data = data; } } @@ -44,30 +42,24 @@ } public int getStatus() { - return status; + if ((data == null) || (length == 0)) { + return 0; + } else { + return (int) (data[0] & 0xFF); + } } protected void setMessage(byte[] data, int length) throws InvalidMidiDataException { - //FIXME - /** - * this method should throw out IndexOutOfBoundsException when - * I use negative length - */ - if (length < 0) - throw new IndexOutOfBoundsException(); + if ((length < 0) || (length > data.length)) { + throw new IndexOutOfBoundsException("length out of bounds: " + length); + } - byte[] tdata = new byte[length]; - if (length == 0 && data != null) { - status = 0; - } else { + this.data = new byte[length]; + if (length != 0) { for (int i = 0; i < length; i++) { - tdata[i] = data[i]; + this.data[i] = data[i]; } - status = (int) (data[0] & 0xFF); - this.length = length; } this.length = length; - this.data = tdata; - } } Index: modules/sound/src/main/java/javax/sound/midi/MetaMessage.java =================================================================== --- modules/sound/src/main/java/javax/sound/midi/MetaMessage.java (revision 425597) +++ modules/sound/src/main/java/javax/sound/midi/MetaMessage.java (working copy) @@ -19,35 +19,25 @@ public class MetaMessage extends MidiMessage { public static final int META = 255; - private int type; - - private byte[] data; - + private int dsp; //displacement from begin of array that + //return by method getData() from begin + //of array that contain data + public MetaMessage() { - super(new byte[] { -1, 0 }); - data = new byte[0]; - type = 0; + super(new byte[] {-1, 0}); } protected MetaMessage(byte[] data) { super(data); - if (data.length >= 2) { - type = (int) (data[1] & 0xFF); - } else { - type = 0; + if (data == null) { + throw new NullPointerException(); } - if (data.length > 3) { + if (super.length > 3) { int n = 3; - while (data[n - 1] < 0) + while ((n <= super.length) && (super.data[n - 1] < 0)) n++; - this.data = new byte[data.length - n]; - for (int i = n; i < data.length; i++) { - this.data[i - n] = data[i]; - } - } else { - this.data = new byte[0]; + dsp = n; } - } public Object clone() { @@ -55,15 +45,26 @@ } public byte[] getData() { - return data.clone(); + if ((super.data != null) && (super.length > 3)) { + byte[] bt = new byte[super.length - dsp]; + for (int i = dsp; i < super.length; i++) { + bt[i - dsp] = super.data[i]; + } + return bt; + } else { + return new byte[0]; + } } public int getType() { - return type; + if ((super.data != null) && (super.length >= 2)) { + return (int) (super.data[1] & 0xFF); + } else { + return 0; + } } public void setMessage(int type, byte[] data, int length) throws InvalidMidiDataException { - //FIXME if (type < 0 || type >= 128) { throw new InvalidMidiDataException("Invalid meta event with type " + type); } @@ -76,7 +77,6 @@ throw new NullPointerException(); } super.setMessage(new byte[] { -1, (byte) type, 0 }, 3); - this.data = new byte[0]; } else { int div = 128; int n = 1; @@ -105,15 +105,10 @@ } } super.setMessage(tdata, length + 2 + ln); - this.data = new byte[length]; - if (length > 0) { - for (int i = 0; i < length; i++) - this.data[i] = data[i]; - } + dsp = ln + 2; } } catch (InvalidMidiDataException e) { throw e; } - this.type = type; } }