所以我想制作一个节拍器,并决定使用pyaudio。我知道还有其他方法,但我想以后用它做一些其他的东西。
这是我迄今为止的代码:
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
def play_audio(filename):
wf=wave.open(filename,"rb")
p=pyaudio.PyAudio()
stream_play=p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
data = wf.readframes(CHUNK)
while True:
if data != '':
stream_play.write(data)
data = wf.readframes(CHUNK)
if data == b"":
break
stream_play.stop_stream()
stream_play.close()
p.terminate()
def metronom(bpm):
while True:
play_callback(beep)
time.sleep(60/bpm)
beep="beep-07a.wav"
我以为它成功了,但不幸的是,时间完全错了。我也试过用回调函数,但时间也一样错误。
现在的解决方案是这样的
def metronom(bpm):
while True:
startTime = time.time()
play_callback(beep)
endTime=time.time()-startTime
time.sleep(60/bpm-endTime)
您希望每60/bpm秒调用一次play_audio函数,但函数调用本身需要时间:您需要读取文件、打开流、播放文件(谁知道它有多长(并关闭流。因此,这增加了从一次点击到下一次点击的时间。
要解决这个问题,您可以尝试从睡眠时间中减去运行play_audio函数所需的时间。您还可以尝试在单独的线程上运行play_audio。
如果你的节拍器只需要滴答声,如果你在windows操作系统上,你可以很容易地使用Winsound来创建节拍器,试着跟随。
import winsound
frequency = 25 # Set Frequency To 25 Hertz
duration = 5*1000 # Set Duration To 5000 ms or 5 second
winsound.Beep(frequency, duration)