问候和致敬的编码人员,
我正在尝试解析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 =“ 0x9”
Definitions.NOTE_OFF =“ 0x8”
该代码有点凌乱,并且绝对没有经过优化,但是对于在Midi方面具有丰富专业知识的人来说,它并不是完全必要的。我应该注意,我阅读的大多数MIDI文件都将“音符关闭”用于相应的音符打开。因此,我阅读的大多数歌曲都可以成功阅读,只有很少一些不使用音符,并且我的应用程序未添加音符。
我的问题是这样的:
除了关闭或以0速度打开音符外,还有什么其他方法可以确定何时停止演奏音符?
最佳答案
这些是我知道的停止MIDI音符的方法:
呼叫“ Note Off”(0x80)
以0的速度调用“ Note On”(0x90)
呼叫“关闭所有笔记”(0x58)
同样,可以在不接收“音符关闭”的情况下接收给定频道和音符的第二个“音符打开”事件。在这种情况下,我认为原始的注解应视为已完成。