【问题标题】:MIDI beat clock in JavaJava中的MIDI节拍时钟
【发布时间】:2013-05-10 12:12:02
【问题描述】:

我正在创建鼓机,但在输出 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,试图找到可以帮助我的东西,但我似乎找不到为此设计的任何方法。 如果您有任何建议,请告诉。

干杯。 /M

【问题讨论】:

  • 20.8333ms 比这些计时器要准确得多。您需要的是一个尽可能频繁地运行的计时器,用于检查微时间。如果经过的时间是>= 20.8ms,则发送时钟滴答。重要的是,从长远来看,您是准确的。如果你最后 24 个时钟的节拍与你的节奏平均一致,那么你就没事了。这就是为什么您应该在开始发送时钟滴答时保留初始偏移量,并在计时器中与它进行比较。
  • 这真的有问题吗?每次节拍你会偏离 0.0016%。这相当于每 365 天只损失 14 小时。对于只打鼓的东西来说,这似乎是一个合理的损失。

标签: java asynchronous midi outputstream


【解决方案1】:

根据this link,您可以使用 Java 5 中提供的 Object.wait(millis, nanos) 和 Thread.sleep(millis, nanos)。 如果您想安排线程,建议使用 ScheduledThreadPoolExecutor。

我也找到了this library,也许值得一试。

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2021-10-27
    相关资源
    最近更新 更多