aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/jsyn/midi/MessageParser.java45
-rw-r--r--src/main/java/com/jsyn/midi/MidiSynthesizer.java4
2 files changed, 37 insertions, 12 deletions
diff --git a/src/main/java/com/jsyn/midi/MessageParser.java b/src/main/java/com/jsyn/midi/MessageParser.java
index d0f5d4d..4ef119a 100644
--- a/src/main/java/com/jsyn/midi/MessageParser.java
+++ b/src/main/java/com/jsyn/midi/MessageParser.java
@@ -28,44 +28,58 @@ public class MessageParser {
private int MASK_14BIT = (1 << 14) - 1;
public void parse(byte[] message) {
- int status = message[0];
+ parse(message, /* offset= */ 0, message.length);
+ }
+
+ public void parse(byte[] message, int offset, int length) {
+ checkMessageLength(/* expectedLength= */ 1, length);
+ int status = message[offset];
int command = status & 0xF0;
int channel = status & 0x0F;
switch (command) {
case MidiConstants.NOTE_ON:
- int velocity = message[2];
+ checkMessageLength(/* expectedLength= */ 3, length);
+ int velocity = message[offset + 2];
if (velocity == 0) {
- noteOff(channel, message[1], velocity);
+ noteOff(channel, message[offset + 1], velocity);
} else {
- noteOn(channel, message[1], velocity);
+ noteOn(channel, message[offset + 1], velocity);
}
break;
case MidiConstants.NOTE_OFF:
- noteOff(channel, message[1], message[2]);
+ checkMessageLength(/* expectedLength= */ 3, length);
+ noteOff(channel, message[offset + 1], message[offset + 2]);
break;
case MidiConstants.POLYPHONIC_AFTERTOUCH:
- polyphonicAftertouch(channel, message[1], message[2]);
+ checkMessageLength(/* expectedLength= */ 3, length);
+ polyphonicAftertouch(channel, message[offset + 1], message[offset + 2]);
break;
case MidiConstants.CHANNEL_PRESSURE:
- channelPressure(channel, message[1]);
+ checkMessageLength(/* expectedLength= */ 2, length);
+ channelPressure(channel, message[offset + 1]);
break;
case MidiConstants.CONTROL_CHANGE:
- rawControlChange(channel, message[1], message[2]);
+ checkMessageLength(/* expectedLength= */ 3, length);
+ rawControlChange(channel, message[offset + 1], message[offset + 2]);
break;
case MidiConstants.PROGRAM_CHANGE:
- programChange(channel, message[1]);
+ checkMessageLength(/* expectedLength= */ 2, length);
+ programChange(channel, message[offset + 1]);
break;
case MidiConstants.PITCH_BEND:
- int bend = (message[2] << 7) + message[1];
+ checkMessageLength(/* expectedLength= */ 3, length);
+ int bend = (message[offset + 2] << 7) + message[offset + 1];
pitchBend(channel, bend);
break;
+ default:
+ break; // We ignore unsupported commands.
}
}
@@ -117,6 +131,17 @@ public class MessageParser {
}
}
+ private void checkMessageLength(int expectedLength, int actualLength) {
+ if (actualLength < expectedLength) {
+ throw new IllegalArgumentException(
+ "Expected message of at least "
+ + expectedLength
+ + " bytes but got "
+ + actualLength
+ + " bytes.");
+ }
+ }
+
public void nonRegisteredParameter(int channel, int index14, int value14) {
}
diff --git a/src/main/java/com/jsyn/midi/MidiSynthesizer.java b/src/main/java/com/jsyn/midi/MidiSynthesizer.java
index 1f5485c..86834d7 100644
--- a/src/main/java/com/jsyn/midi/MidiSynthesizer.java
+++ b/src/main/java/com/jsyn/midi/MidiSynthesizer.java
@@ -110,8 +110,8 @@ public class MidiSynthesizer extends MessageParser {
multiSynth.setPitchBend(channel, offset);
}
- public void onReceive(byte[] bytes, int i, int length) {
- parse(bytes); // TODO
+ public void onReceive(byte[] bytes, int offset, int length) {
+ parse(bytes, offset, length);
}
}