我正在编写一些代码来测试使用 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)毫秒。这似乎表明没有间隙 - 但每次运行代码时我都能清楚地听到间隙。
最佳答案
既然你有 sleep ,你应该计算你应该睡多长时间,而不是每次尝试睡相同的时间 - 计算你实际需要多长时间才能演奏下一个音符并睡那么多时间。即
long tic = System.currentTimeMillis();
player.playNote(10, notes[i]);
long time_spent = System.currentTimeMillis() - tic;
Thread.sleep(200 - time_spent);
关于Java:for循环的第一次迭代需要更长的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37926269/