2 回答

TA貢獻1775條經(jīng)驗 獲得超8個贊
播放聲音來模擬普通的節(jié)拍器不需要“實時”功能。
看起來您使用Tkinter框架創(chuàng)建了GUI。root.after()允許您延遲調用函數(shù)。您可以使用它來實現(xiàn)刻度:
def tick(interval, function, *args):
root.after(interval - timer() % interval, tick, interval, function, *args)
function(*args) # assume it doesn't block
tick()運行function與給定的args每interval毫秒。單個刻度的持續(xù)時間受root.after()精度影響,但從長遠來看,穩(wěn)定性僅取決于timer()功能。
這是一個打印一些統(tǒng)計數(shù)據(jù)(240每分鐘心跳數(shù))的腳本:
#!/usr/bin/env python
from __future__ import division, print_function
import sys
from timeit import default_timer
try:
from Tkinter import Tk
except ImportError: # Python 3
from tkinter import Tk
def timer():
return int(default_timer() * 1000 + .5)
def tick(interval, function, *args):
root.after(interval - timer() % interval, tick, interval, function, *args)
function(*args) # assume it doesn't block
def bpm(milliseconds):
"""Beats per minute."""
return 60000 / milliseconds
def print_tempo(last=[timer()], total=[0], count=[0]):
now = timer()
elapsed = now - last[0]
total[0] += elapsed
count[0] += 1
average = total[0] / count[0]
print("{:.1f} BPM, average: {:.0f} BPM, now {}"
.format(bpm(elapsed), bpm(average), now),
end='\r', file=sys.stderr)
last[0] = now
interval = 250 # milliseconds
root = Tk()
root.withdraw() # don't show GUI
root.after(interval - timer() % interval, tick, interval, print_tempo)
root.mainloop()
速度僅拍打一拍:我的機器上為240±1。

TA貢獻1865條經(jīng)驗 獲得超7個贊
由于需要處理器與其他程序共享自身,因此做任何需要時間精度的事情都非常困難。不幸的是,對于定時關鍵程序,操作系統(tǒng)可以隨時選擇切換到另一個進程。這可能意味著它可能要等到明顯的延遲后才能返回程序。導入時間后使用time.sleep這是一種嘗試平衡嗶嗶聲之間時間的更一致的方法,因為處理器的“理由”減少了。盡管Windows上的睡眠默認設置為15.6毫秒,但我認為您無需播放超過64Hz的拍子??磥砟谑褂枚嗑€程來嘗試解決您的問題,但是,線程的python實現(xiàn)有時會強制線程按順序運行。這將使您從流程中退出的情況變得更加糟糕。
我認為最好的解決方案是以所需的頻率生成包含節(jié)拍器蜂鳴聲的聲音數(shù)據(jù)。然后,您可以以操作系統(tǒng)熟悉的方式播放聲音數(shù)據(jù)。由于系統(tǒng)知道如何以可靠的方式處理聲音,因此您的節(jié)拍器將開始工作。
令人失望的是,但是對關鍵應用程序進行計時非常困難,除非您想弄清正在使用的系統(tǒng)。
添加回答
舉報