Python 2.7 Python中节拍器脚本中的计时问题(使用Pygame)

Python 2.7 Python中节拍器脚本中的计时问题(使用Pygame),python-2.7,time,pygame,midi,Python 2.7,Time,Pygame,Midi,我正在尝试编写一个节拍器脚本,它给我提供音频反馈,并向合成器发送MIDI信息。我在Linux Mint 16上使用Python 2.7.5+和Pygame 1.9.1.release。我对MIDI部分没意见。让我烦恼的是时间 首先,我基本上是这样做的: import time import pygame.mixer pygame.mixer.init() sound = pygame.mixer.Sound('click.wav') interval = 0.5 #should be equ

我正在尝试编写一个节拍器脚本,它给我提供音频反馈,并向合成器发送MIDI信息。我在Linux Mint 16上使用Python 2.7.5+和Pygame 1.9.1.release。我对MIDI部分没意见。让我烦恼的是时间

首先,我基本上是这样做的:

import time
import pygame.mixer

pygame.mixer.init()
sound = pygame.mixer.Sound('click.wav')

interval = 0.5 #should be equivalent to 120 bpm

t0 = time.time()

while True: #infinite loop, use keyboard interrupt Ctrl-C
    if time.time() - t0 >= interval:
        sound.play()
        t0 = time.time()
然而,这是相当不稳定的,不可能用乐器演奏

我还查看了time.clock:

…以及pygame.time.Clock,特别是pygame.time.Clock.tick_busy_循环,该循环通过消耗更多处理器来提供更好的精度:

import pygame.time
import pygame.mixer

pygame.mixer.init()
#pygame.time has no init function

sound = pygame.mixer.Sound('click.wav')
clock = pygame.time.Clock()

interval = 0.5 #should be equivalent to 120 bpm

time_passed = 0
clock.tick_busy_loop()

while True: #infinite loop, use keyboard interrupt Ctrl-C
    time_passed += clock.tick_busy_loop()
    if time_passed >= interval:
        sound.play()
        time_passed = 0
所有这些都产生了同样的问题。虽然,我必须承认,当我尝试这些最小的例子时,pygame.time解决方案是非常稳定的。这里的问题是,在我的实际脚本中,我做了一些计算,比如递增计数器和在while循环中发送MIDI消息,这似乎会影响循环所用的时间以及单击“开始”以结巴和绊倒

我看了一下,但是我不太了解midi文件。这有帮助吗?一些解释会很有帮助

此外,我还试图

import os
os.nice(-19)
开始时,我们希望获得更高的流程优先级,但没有明显的改进

我想知道我怎样才能获得像Cubase、Ableton和Logic这样的普通Daw一样稳定的节拍器。我读过关于生成或预录有关节奏的音频样本并链接这些样本以实现更高预测的方法,但我确实希望避免这种方法,因为它看起来非常费劲

是否有一些聪明的方法可以使用稳定的pygame.time variant并在其他地方进行处理

如果有任何用处:以下是我正在运行的实际while循环:

bpm = 80.0
beats_in_one_second = bpm/60.0
midi_send_interval = beats_in_one_second/24.0 #MIDI convention

playing = True
player.write_short(250) #start
frame_count = 0
quarter_count = 0
time_0 = time.time()

while playing:
    if time.time() - time_0 >= midi_send_interval:
        player.write_short(248) #clock tick
        time_0 = time.time()
        frame_count += 1
        if frame_count == 24:
            sound.play()
            quarter_count += 1
            frame_count = 0
            if quarter_count == 16:
                playing = False

player.write_short(252) #stop

问题是,MIDI标准要求每四分之一音符包含24条信息,这大大提高了对精确度的要求。

为什么不使用?您可能应该使用不同的MIDI方法,但如果您只需要调用声音。定期播放,每秒不超过60次,则可以。这里有两个相关的代码示例:a和。你们能在MIDI解决方案上使用Elaborate吗?我不知道如何使用这些时间戳,而且我在网上找不到合适的教程。是否可以使用您建议的方法触发声音并同时发送MIDI信号?
bpm = 80.0
beats_in_one_second = bpm/60.0
midi_send_interval = beats_in_one_second/24.0 #MIDI convention

playing = True
player.write_short(250) #start
frame_count = 0
quarter_count = 0
time_0 = time.time()

while playing:
    if time.time() - time_0 >= midi_send_interval:
        player.write_short(248) #clock tick
        time_0 = time.time()
        frame_count += 1
        if frame_count == 24:
            sound.play()
            quarter_count += 1
            frame_count = 0
            if quarter_count == 16:
                playing = False

player.write_short(252) #stop