MIDI 序列,注释命令并不总是跟随注释关闭

Xav*_*Xav 2 java midi sequence

向编码员们致以问候和问候,

我正在尝试解析 MIDI 序列并从中获取音符持续时间。当我收到音符命令时,我会向前查找以查找同一键的音符关闭命令或速度为 0 的音符命令。这是有问题的代码块(可能不需要)。

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;
                        }
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

定义.NOTE_ON = "0x9"

定义.NOTE_OFF = "0x8"

代码有点混乱,而且绝对没有优化,但对于在 midi 方面有丰富专业知识的人来说,它不完全是必要的。我应该注意到,我读到的大多数 MIDI 文件都使用音符关闭来代替相应的音符打开。因此,我读的大多数歌曲都可以成功读取,只有少数歌曲没有使用音符关闭,并且我的应用程序没有添加音符。

我的问题是:除了速度为 0 的音符关闭或音符打开之外,还有什么其他方法可以确定音符何时停止播放?

Dav*_*lle 5

以下是我知道的停止 MIDI 音符的方法:

  1. 调用“音符关闭”(0x80)
  2. 以 0 的速度调用“Note On”(0x90)
  3. 调用“所有音符关闭”(0x58)

此外,可以在未接收音符关闭的情况下接收给定通道和音符的第二音符开启事件。既然如此,我相信原来的Note On应该算完成了。