pgonzaleznetwork pgonzaleznetwork - 13 days ago 6
Java Question

InvalidMidiDataException: command out of range

I have this app from Head First Java

import javax.sound.midi.*;

public class MiniMiniMusicApp{
public static void main(String[] args){
MiniMiniMusicApp mini = new MiniMiniMusicApp();
mini.play();
}
public void play(){
try{
Sequencer player = MidiSystem.getSequencer();
player.open();
Sequence seq = new Sequence(Sequence.PPQ,4);
Track track = seq.createTrack();
ShortMessage a = new ShortMessage();
a.setMessage(114,1,44,100);
MidiEvent noteOn = new MidiEvent(a,1);
track.add(noteOn);

ShortMessage b = new ShortMessage();
b.setMessage(128,1,44,100);
MidiEvent noteOff = new MidiEvent(b,16);
track.add(noteOff);
player.setSequence(seq);

player.start();

} catch(Exception ex){
ex.printStackTrace();
System.out.println("damn");
}
}
}


And this throws the following exception at runtime

javax.sound.midi.InvalidMidiDataException: command out of range: 0x72
at javax.sound.midi.ShortMessage.setMessage(ShortMessage.java:280)
at MiniMiniMusicApp.play(MiniMiniMusicApp.java:15)
at MiniMiniMusicApp.main(MiniMiniMusicApp.java:6)


I read some docs on setMessage and it seems the exception is thrown when you pass an invalid MidiMessage but I'm simply following the example from the book. I've read on other forums and it appears that this code works for other people.

Any idea on what is causing the issue? Can you try running this on your end and see if it works? At least that'll tell me if it's something on my environment.

Answer

You probably want to send a NoteOn message (144, not 114). The class ShortMessage contains constants which prevent such mistakes. You could use it like this:

import static javax.sound.midi.ShortMessage.*;

a.setMessage(NOTE_ON, 1, 44, 100);

Such code is probably easier to read for most people than directly using the numbers.

Comments