Python中的精确循环计时 [英] Precise loop timing in Python

查看:81
本文介绍了Python中的精确循环计时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于这个项目,我正在设计一个音序器/鼓机,它应该能够用精确的节奏.示例:每 2 秒 16 个音符(即在音乐术语中,BPM 120 每小节 16 个 1/16 音符),即每 125 毫秒一个音符.

For this project I'm designing a sequencer/drummachine that should be able to send MIDI notes with a precise tempo. Example: 16 notes per 2 seconds (i.e. in music terminology sixteen 1/16-notes per bar at BPM 120), i.e. one note every 125 milliseconds.

我在考虑:

import time

def midi_note_send(...):
    ....

while True:
    midi_note_send(...)
    time.sleep(0.125)

如果我这样做,如何确保它正好是 125 毫秒?这个循环的 1000 次迭代是否有使用 126 秒而不是 125 秒的风险?如果是这样,如何有一个更精确的循环?

If I do like this, how to be sure it will be exactly 125 milliseconds? Isn't there a risk that 1000 iterations of this loop will be using 126 seconds instead of 125 seconds? If so, how to have a more precise loop?

最后一点:一台好的鼓机应该能够在 1 小时内保持 120 BPM 的节奏,精度误差 <1 秒.
使用的平台:Linux + RaspberryPi 但这个问题一般有效.

Final note: a good drummachine should be able to keep a 120 BPM rythm during 1 hour, with a precision error < 1 second.
Used platform: Linux + RaspberryPi but this question is valid in general.

推荐答案

正如我在此处

import time
def drummer():
    counter = 0
    # time.sleep(time.time() * 8 % 1 / 8) # enable to sync clock for demo
    while counter < 60 * 8:
        counter += 1
        print time.time()
        time.sleep(.125 - time.time() * 8 % 1 / 8)

这个计时器会调整每个节拍并重新调整.

This timer adjusts every beat and realigns.

而且调整几乎不需要时间:

And the adjustment takes almost no time:

timeit.timeit("time.time() * 8 % 1 / 8", number=1000000)
0.2493131160736084

这意味着每次执行大约需要 0.25 微秒

which means every time it does that it takes about 0.25 microseconds

为了准确:

1488490895.000160
1488490895.125177
1488490895.250167
1488490895.375151
1488490895.500166
1488490895.625179
1488490895.750178
1488490895.875153

音符之间的漂移约为 28 微秒.在本地运行更长的时间会产生约 130 微秒的总漂移 (+- 65 微秒),但是,由于它每节拍与时钟同步,因此不会随着时间的推移而发生偏差.

~28 microseconds of drift between notes. Running it locally for a longer time yields ~130μs of total drift (+- 65μs), but, as it syncs to the clock every beat, it won't deviate over time.

这篇关于Python中的精确循环计时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆