Java中的MIDI节拍时钟
我正在制作一个鼓机,我在输出MIDI节拍时钟时遇到了一些问题。 为简单起见,我通过调用Thread.sleep(_time)将内部时钟设置为运行,其中_time是由以下代码计算的第十六个音符的时间量: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() {
/**
* 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小时。这似乎是一个合理的损失的东西,只是发挥鼓拍。