我想知道使用jack audio api使我的应用程序与时基主应用程序保持同步的正确方法。
让我们说Hydrogen drum machine在主模式下运行,我想在氢气正在播放的每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)
所以我在没有睡眠时间的情况下运行循环,并在每次迭代时检查当前节拍是否已经结束。
这对我来说似乎有点肮脏和不精确。那么解决这个问题的正确方法是什么呢?
答案 0 :(得分: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()