我尝试制作一个非常简单的节拍器,运行速度为 30 bpm:
While True:
winsound.Beep(1000, 200)
time.sleep(2 - 0.2)
然后,我打开手机上的节拍器应用程序,伴随着电脑中的嘟嘟声,随着时间的推移,节拍器变得越来越不精确。 还有另一种方法可以执行“time.sleep()”吗?甚至是“time.sleep()”的罪恶感吗?
最佳答案
这在多任务操作系统上很难做到:系统不容易为您提供您请求的准确 sleep
延迟。请参阅How accurate is python's time.sleep()?了解详情。
但是我们可以通过测量时间跨度和调整 sleep 延迟来相当接近。 Python 3.3+ 提供 time.perf_counter
,它应该非常适合测量时间间隔,尽管确切的精度取决于您的操作系统和硬件。
这是一个简单的演示,仅打印每个刻度的请求时间延迟和测量时间延迟之间的差异。最初的输出有点草率,但很快就稳定下来,给出请求间隔 10 微秒以内的滴答声。然而,播放声音比打印到终端需要更多的系统资源,这可能会影响该技术的精度。为了获得最佳结果,请最大限度地减少计算机上的任务负载,尤其是在单核的情况下。
我已将延迟设置为 0.2 秒 = 300 bpm。较慢的节拍率可能会导致较低精度,因为在每个 sleep 周期内,CPU 有更多的时间来执行其他任务,这可能会导致 sleep 时间比请求的时间稍长。
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、YMMV 的旧单核 32 位 2GHz 机器。
关于python - 如何制作精确的节拍器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51389691/