【问题标题】:jack audio - sync application to master插孔音频 - 将应用程序同步到主控
【发布时间】:2018-02-16 14:13:21
【问题描述】:

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

假设我有 Hydrogen drum machine 在主模式下运行,我想在 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)

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

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

【问题讨论】:

  • 你能发布你遇到的错误吗?
  • 我没有收到任何错误,此代码有效。但我无法想象这是使用 api 的预期方式

标签: python audio synchronization jack


【解决方案1】:

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

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

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()

【讨论】:

    猜你喜欢
    • 2017-10-13
    • 2012-05-16
    • 2012-11-09
    • 2013-03-08
    • 2012-04-30
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多