MIDI序列,注意命令并不总是后退音符

时间:2014-02-07 19:02:22

标签: java sequence midi

致编辑和致敬,

我尝试解析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;
                        }
                    }
                }
            }
        }
    }
}

Definitions.NOTE_ON =&#34; 0x9&#34;

Definitions.NOTE_OFF =&#34; 0x8&#34;

代码有点凌乱,绝对没有优化,但对于在midi具有丰富专业知识的人来说,它不应该是完全必要的。我应该注意,我读过的大多数MIDI文件都使用音符关闭相应的音符。因此,我阅读的大多数歌曲都是成功阅读的,只有少数人不会使用笔记关闭而且我的应用程序没有添加笔记。

我的问题是: 除了音符关注或注意速度为0时,还有哪些方法可以确定音符何时停止播放?

1 个答案:

答案 0 :(得分:4)

这些是我知道停止MIDI音符的方法:

  1. 调用“Note Off”(0x80)
  2. 以速度0
  3. 调用“Note On”(0x90)
  4. 调用“所有笔记关闭”(0x58)
  5. 此外,可以在未收到Note Off的情况下接收给定频道和音符的第二个Note On事件。在这种情况下,我认为最初的Note On应该被认为已经完成。