Java中的MIDI节拍时钟

Java中的MIDI节拍时钟,java,asynchronous,midi,outputstream,Java,Asynchronous,Midi,Outputstream,我正在制作一个鼓机,我在输出MIDI节拍时钟时遇到了一些问题。 为简单起见,我通过调用Thread.sleep(_time)将内部时钟设置为运行,其中_time是由以下代码计算的第十六个音符的时间量: /** * Calculates the length of a semiquaver in the sequencer * @return the time of a semiquaver in milliseconds */ private void calculateTempo() {

我正在制作一个鼓机,我在输出MIDI节拍时钟时遇到了一些问题。 为简单起见,我通过调用Thread.sleep(_time)将内部时钟设置为运行,其中_time是由以下代码计算的第十六个音符的时间量:

/**
 * Calculates the length of a semiquaver in the sequencer
 * @return the time of a semiquaver in milliseconds
 */
private void calculateTempo()
{
    Log.i(DEBUG_TAG , "Calculated tempo.");

    /**
     * Fjärdedelsnot
     */
    _quarterNote = 60000/_tempo;

    /**
     * Sextondel
     */
    _sixteenthNote = (_quarterNote/4);


}
_tempo是BPM的整数值。 正如我所说,我的鼓机运行良好,但当输出节拍时钟时,我遇到了问题。 从属设备中的节拍时钟预期每四分之一音符接收24个脉冲,这使我们的速率为每十六个音符接收6个脉冲。 我正在使用timer.scheduleAtFixedRate将消息添加到输出队列

假设我们的节奏为120 BPM,那么每四分之一音符的时间为60000/120=500,即每十六分之一音符的时间为125毫秒。 每十六个音符应有六个脉冲,125/6=20.83333。。你可以明白为什么这让我有点为难。 scheduleAtFixedRate只需要毫秒作为参数,因此我必须制作一个精度更高的计数器,但即使我使用纳秒,过一段时间后事情也会开始漂移

我一直在仔细研究JavaMIDIAPI,试图找到一些对我有帮助的方法,但我似乎找不到任何为此设计的方法。 如果你有任何建议,请告诉我

干杯。 /M

根据需要,可以从Java5使用Object.wait(毫秒,纳米)和Thread.sleep(毫秒,纳米)。 如果要调度线程,建议使用ScheduledThreadPoolExecutor

我也发现,也许值得一看


祝你好运

20.8333ms
远比这些计时器准确。你需要的是一个尽可能经常运行的计时器,用来检查微时间。如果经过的时间
>=20.8ms
,则发送时钟滴答声。重要的是,从长远来看,你是准确的。如果你的最后24个时钟按你的平均节奏滴答作响,那么你就没事了。这就是为什么当你开始发送时钟信号时,你应该保持初始偏移量,并与计时器中的偏移量进行比较。这真的是个问题吗?你每拍都会被罚0.0016%。这相当于每365天只损失14小时。这似乎是一个合理的损失的东西,只是发挥鼓拍。