0

我想知道使用jack audio api使我的应用程序与时基主应用程序保持同步的正确方法。

假设我有Hydrogen 鼓机以主模式运行,我想在 Hydrogen 播放的每个 1/4 音符上打印一条消息。

这就是我会做的直观(使用python):

#!/usr/bin/env python3

import time
import jack

client = jack.Client('klicker')

def print_msg (last_tick):
    state, pos = client.transport_query()
    if state == jack.ROLLING:
        if pos['tick'] < last_tick:
            print ("klick")

    return pos['tick']

with client:
   last_tick = 0
   while True:
      last_tick = print_msg (last_tick)
      time.sleep(0.00002)

所以我正在运行一个睡眠时间很少的循环,如果当前节拍已经结束,则检查每次迭代。

这对我来说似乎有点肮脏和不精确。那么解决这个问题的正确方法是什么?

4

1 回答 1

0

最后,我找到了一个更精确的解决方案:

首先,我们要使用进程回调而不是无限循环。

def process (f):

每次调用此回调时,都会f处理帧数。采样率告诉我们我们将在 1 秒内处理多少帧。通过将其乘以 60 并除以数量,beats per minute我们得到在一个节拍中处理的帧数。

#!/usr/bin/env python3

import jack
client = jack.Client('Klick')
frame_counter = 0

@client.set_process_callback
def process (f):
    global frame_counter
    state, pos = client.transport_query()

    if state == jack.ROLLING:
        frame_counter += f

        # how many frames are get processed in 1 beat?
        frames_per_beat = client.samplerate * 60 / pos['beats_per_minute']

        # did we process enough frames for 1 beat?
        if frame_counter >= frames_per_beat:
            print ('klick')
            frame_counter -= frames_per_beat


with client:
    client.activate()
    input()
于 2018-04-24T22:35:19.883 回答