【问题标题】:Using pyaudio to build a Metronome; wrong timing使用pyaudio构建节拍器;时间错误
【发布时间】:2022-02-09 02:29:30
【问题描述】:

所以我想构建一个节拍器并决定使用 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)

【问题讨论】:

    标签: python audio time pyaudio


    【解决方案1】:

    您希望每 60/bpm 秒调用一次 play_audio 函数,但函数调用本身需要时间:您需要读取文件、打开流、播放文件(谁知道它有多长)并关闭溪流。这样就增加了从一次点击到下一次点击的时间。

    要解决此问题,您可以尝试从睡眠时间中减去运行 play_audio 函数所需的时间。您还可以尝试在单独的线程上运行 play_audio。

    【讨论】:

    • 感谢您的回答!这样效果更好。
    【解决方案2】:

    如果您的节拍器只需要一个滴答声,并且如果您使用的是 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)
    

    【讨论】:

    • 谢谢,但我不想这样做
    • 所以 margalo'a 的答案似乎是正确的路径。您可以创建一个线程,以毫秒为单位从 datetime 获取滴答时间戳,并与之前的滴答时间戳记录进行比较。希望你的处理时间比你的节拍器频率短
    猜你喜欢
    • 1970-01-01
    • 2015-11-11
    • 2020-07-04
    • 1970-01-01
    • 2013-12-03
    • 2019-02-24
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    相关资源
    最近更新 更多