我怎样才能做一个精确的节拍器



我试着做一个非常简单的节拍器,工作频率为30 bpm:

While True:
winsound.Beep(1000, 200)
time.sleep(2 - 0.2)

然后,我打开了手机上的节拍器应用程序和电脑上的嘟嘟声,随着时间的推移,它变得不那么精确了。还有其他方法可以做"time.sleep(("吗?这甚至是"time.sleep(("的内疚吗?

在多任务操作系统上很难做到这一点:系统很难给您所要求的sleep延迟。请参阅python的准确性;是时候睡觉了?详细信息。

但我们可以通过测量时间跨度和调整睡眠延迟来接近。Python 3.3+提供了time.perf_counter,它被认为在测量时间间隔方面非常好,尽管确切的精度取决于您的操作系统和硬件。

这里有一个简单的演示,它只打印每个刻度的请求时间延迟和测量时间延迟之间的差异。最初的输出有点草率,但很快就稳定下来,给出的滴答声在请求间隔的10微秒以内。然而,播放声音比打印到终端需要更多的系统资源,这可能会影响这种技术的精度。为了获得最佳效果,请最大限度地减少机器上的任务负载,尤其是在单核的情况下。

我已经将这里的延迟设置为0.2秒=300 bpm。较慢的拍频可能会使的精度降低,因为在每个睡眠周期中,CPU有更多的时间来执行其他任务,这可能会导致睡眠时间比请求的稍长。

from time import sleep, perf_counter
delay = d = 0.2
print(60 / delay, 'bpm')
prev = perf_counter()
for i in range(20):
sleep(d)
t = perf_counter()
delta = t - prev - delay
print('{:+.9f}'.format(delta))
d -= delta
prev = t

典型输出

300.0 bpm
+0.000262488
+0.000151862
-0.000019085
-0.000011358
+0.000023078
-0.000015817
-0.000004357
+0.000009283
-0.000012252
+0.000020515
-0.000009061
+0.000003249
-0.000011482
+0.000029230
+0.000001554
-0.000023614
-0.000003286
+0.000000127
-0.000003732
+0.000016311

这些结果来自运行Linux的旧单核32位2GHz机器YMMV。

相关内容

最新更新