Java:for循环的第一次迭代需要更长时间

时间:2016-06-20 15:26:18

标签: java for-loop midi lag synthesizer

我正在编写一些代码来测试使用Java中的MIDI库,并遇到了一个问题。在第一个音符之后,音符之间的暂停时间要长得多(事实上几乎是后者的两倍)。我看不出任何理由,因为已经生成了音符序列(因此它不必在循环的第一次迭代中执行那些计算,它只是在演奏音符)。

我想我过去也可能遇到过这个问题的模拟,在没有任何解释的情况下我可以找到它几乎100%的刻度长度来执行仅在第一个刻度上的计算,然后仅使用大约2个所有连续迭代的百分比。

主要代码(摘录):

public void play() {
    MidiPlayer player = new MidiPlayer();
    for (int i = 0; i < NUMNOTES; i++) {
        long tic = System.currentTimeMillis();
        player.playNote(10, notes[i]);
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long toc = System.currentTimeMillis();
        System.out.println(toc - tic);
    }
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

playNote()的代码:

public void playNote(int channel, int note) {
    channels[channel].allNotesOff();
    channels[channel].noteOn(note + 60,  volume);
}

没有'if'语句指定第一个循环,所以所有音符的延迟肯定是一致的,因为所有迭代的执行计算次数应该相同。请注意,时序变量仅用于测试目的,在我包含这些变量之前,效果明显可见。

编辑:我还应该提到产生的输出显示循环的每次迭代采用预期的200(偶尔201)毫秒。它似乎表明没有差距 - 但每次运行代码时我都清楚地听到了差距。

1 个答案:

答案 0 :(得分:1)

因为您有睡眠,所以您应该计算自己应该睡多长时间,而不是每次都尝试睡相同的时间-计算出下一个音符实际需要多长时间才能睡眠。即

    long tic = System.currentTimeMillis();
    player.playNote(10, notes[i]);
    long time_spent = System.currentTimeMillis() - tic;
    Thread.sleep(200 - time_spent);