如何将TimeStamps转换为Ticks(PPQ) - 实时Midi

时间:2011-11-19 10:04:44

标签: java timestamp real-time midi

我正在使用一个实现Receiver的类实时从midi键盘读取MIDI信息,并输出播放的音符。

我按下音符时收到的唯一信息是MidiMessage和timeStamp。

我正在尝试将音符描绘成实际的钢琴乐谱,目前用户必须事先设定bpm。

因此,如果我知道速度为120bpm(例如),我如何使用timeStamps来确定按下音符的长度?

我假设我可以将timeStamps转换为刻度(ppq),然后我可以用它来计算时间。

非常感谢任何帮助。下面是我的Receiver类中的“发送”方法。

'firstStamp'和'secondStamp'变量只是输出音符的长度。我发布了一个音符时取出了timeStamp,并在按下它时减去了timeStamp。

@Override
public void send(MidiMessage message, long timeStamp) {

    String  strMessage = null;

    if (firstStamp == 0) {
        firstStamp = timeStamp;
        secondStamp = timeStamp;
    }

    firstStamp = secondStamp;
    secondStamp = timeStamp;

    stampDif = (secondStamp - firstStamp);

    if (message instanceof ShortMessage) {

        strMessage = decodeMessage((ShortMessage) message, timeStamp);


    } else if (message instanceof MetaMessage) {

        strMessage = decodeMessage((MetaMessage) message);

    } else if (message instanceof SysexMessage) {

        strMessage = decodeMessage((SysexMessage) message);

    } else {
        strMessage = "other message" + message.getStatus();
    }
    r_out.println("Timestamp: " + timeStamp + " " + strMessage);
    r_printStream.println("Timestamp: " + timeStamp + " " + strMessage);

}

1 个答案:

答案 0 :(得分:2)

如果时间戳以毫秒为单位,那么您可以将其转换为这样的滴答:

long ticks = timestamp * bpm / (1000 * 60); 
由于时间戳可能是从1970年1月1日开始的,所以你会得到一个很高的开始时间。所以如果你想让你的第一个“勾号”为0,你需要跟踪这是否是你第一次看到的事件。

if (tickOffset == -1) { // Using -1 as not initialized
    tickOffset = ticks;
}
ticks = ticks - tickOffset;