3

我正在编写一些代码来测试使用 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)毫秒。这似乎表明没有差距——但每次运行代码时我都清楚地听到了差距。

4

1 回答 1

1

既然你有睡眠,你应该计算你应该睡多长时间,而不是每次都尝试睡相同的时间 - 计算你实际上需要多长时间才能演奏下一个音符并睡那么多时间。IE

    long tic = System.currentTimeMillis();
    player.playNote(10, notes[i]);
    long time_spent = System.currentTimeMillis() - tic;
    Thread.sleep(200 - time_spent);
于 2018-12-30T19:59:14.530 回答