我正在创建一台鼓机,但在输出 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 只需要毫秒作为参数,所以我必须制作一个精度更高的计数器,但即使我使用纳秒,一段时间后事情也会开始漂移..
我真的一直在梳理Java MIDI api,试图找到可以帮助我的东西,但我似乎找不到为此设计的任何方法。如果您有任何建议,请告诉。
干杯。/米