Question

Greetings and salutations fellow coders,

I'm trying to parse a MIDI sequence and get note durations from it. When I get a note on command I do a look ahead to find either a note off command for the same key or a note on command with a velocity of 0. Here is the code block in question(probably not needed).

for (Track track : sequence.getTracks()) 
{
    for (int i = 0; i < track.size(); i++) 
    {
        MidiEvent event = track.get(i);
        MidiMessage message = event.getMessage();

        if (message instanceof ShortMessage) 
        {
            ShortMessage sm = (ShortMessage) message;
            long timeStamp = event.getTick();
            String temp = "0x" + Integer.toHexString(sm.getCommand());

            if (temp.contains(Definitions.NOTE_ON))
            {
                // look ahead for note off and find duration

                for (int j = i; j < track.size(); j++) 
                {
                    MidiEvent event2 = track.get(j);
                    MidiMessage message2 = event2.getMessage();

                    if (message2 instanceof ShortMessage)
                    {
                        ShortMessage sm2 = (ShortMessage) message2;
                        long timeStamp2 = event2.getTick();
                        temp = "0x" + Integer.toHexString(sm2.getCommand());

                        if (temp.contains(Definitions.NOTE_OFF) && sm2.getData1() == sm.getData1()) 
                        {
                                song.addNote(trackNumber, sm.getData1(), timeStamp, timeStamp2 - timeStamp, sm.getData2());
                                break;
                        }
                            //another valid way of turning a note off is playing a note on with a velocity of 0
                        else if (temp.contains(Definitions.NOTE_ON) && sm2.getData1() == sm.getData1() && sm2.getData2() == 0)
                        {
                            song.addNote(trackNumber, sm.getData1(), timeStamp, timeStamp2 - timeStamp, sm.getData2());
                            break;
                        }
                    }
                }
            }
        }
    }
}

Definitions.NOTE_ON = "0x9"

Definitions.NOTE_OFF = "0x8"

The code is a little messy and definitely not optimized, but it shouldn't entirely be necessary for people with great expertise in midi. I should note that most MIDI files I read use note off for the corresponding note on. So most the songs I read are read successfully there are just a few that don't use note off and my application is not adding the notes.

My question is this: What other ways than note off or note on with a velocity of 0 determines when a note stops playing?

Was it helpful?

Solution

These are the ways I know to stop a MIDI note:

  1. Call "Note Off" (0x80)
  2. Call "Note On" (0x90) with velocity of 0
  3. Call "All Notes Off" (0x58)

Also, a second Note On event for a given channel and note can be received without having received a Note Off. In this case, I believe the original Note On should be considered finished.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top