Search code examples
javamidijavasoundjavax.sound.midi

Editing midi events


I’m attempting to editing the pitch of existing midi notes in a sequence by moving the graphical notes (rectangles) in a piano roll editor up or down. Reading over the APIs and online documents, it doesn’t get very specific on how to edit existing notes. From the best I can tell, I need to use the setMessage() method to overwrite the existing ShortMessage. Here’s what I’ve got right now:

public void changePitch(int pitchUpOrDown) {
    MidiMessage message =  this.getMessage();
    message.setMessage(___?, ____?, ____? + pitchUpOrDown, ____?);
}

I’m calling changePitch() from a JPanel by mouse-dragging a note, and I’m sending either +1 or –1 as the increment by which the pitch will be adjusted. What I can’t find is the values that need to go in the other four blank parameters of the setMessage() call. Logically, I want to keep the existing values for command, channel and timestamp, but how do I access these existing values so that I can put them in the blanks? I’ve tried things like message.command, or message[0], etc. but they don’t work. Also, in the documentation, the args for set Message are shown as (byte[] data, int length). The explanation for these args is really vague, and they definitely don’t match the args I used to create the ShortMessage in the first place. Any suggestions?


Solution

  • Cast the MidiMessage down to ShortMessage and then you can get the pitch and velocity as data1 and data2:

    if (message instanceof ShortMessage) {
        ShortMessage shortMessage = (ShortMessage) message;
    
        if(shortMessage.getCommand() == ShortMessage.NOTE_ON) {
            int channel = shortMessage.getChannel();
            int pitch = shortMessage.getData1();
            int vel = shortMessage.getData2();
            if(vel > 0) {
                shortMessage.setMessage(ShortMessage.NOTE_ON, channel, pitch + pitchUpOrDown, vel);
            }
        }
    }
    

    You might need to change the next NOTE_OFF message as well. This will either be a shortMessage with a NOTE_OFF command, or a NOTE_ON command with a velocity of 0.