带twisted的Python metronome:如何为迭代传递参数?

带twisted的Python metronome:如何为迭代传递参数?,python,twisted,metronome,Python,Twisted,Metronome,我想用Python构建一个节拍器 我有两个声音文件。每秒钟播放一次第一个声音文件,每四秒钟播放一次第二个声音文件 我找到了twisted模块,但不知道如何传递参数并对其进行迭代。因此,我有一个变量计数器,我想迭代它,但它不适用于以下代码: import simpleaudio as sa from twisted.internet import task from twisted.internet import reactor def beat(bpm, counter): time

我想用Python构建一个节拍器

我有两个声音文件。每秒钟播放一次第一个声音文件,每四秒钟播放一次第二个声音文件

我找到了twisted模块,但不知道如何传递参数并对其进行迭代。因此,我有一个变量计数器,我想迭代它,但它不适用于以下代码:

import simpleaudio as sa
from twisted.internet import task
from twisted.internet import reactor


def beat(bpm, counter):
    timeout = 60/bpm
    l = task.LoopingCall(play_beat, counter=counter)
    l.start(timeout)
    reactor.run()


def play_beat(counter):
    counter += 1
    print(counter) #This prints always 2, I am expecting an iteration like 2, 3, 4, 5, 6 ...
    if counter % 4 == 0:
        wave_obj = sa.WaveObject.from_wave_file("wav/beat_end.wav")
    else:
        wave_obj = sa.WaveObject.from_wave_file("wav/beat_start.wav")
    play_obj = wave_obj.play()
    play_obj.wait_done()
    pass

beat(60, 1)

这是另一个解决方案

import simpleaudio as sa
from twisted.internet import task
from twisted.internet import reactor

def beat(bpm, wave_obj):
    timeout = 60.0 / bpm
    l = task.LoopingCall(play_beat, wave_obj)
    l.start(timeout)

def play_beat(wave_obj):
    wave_obj.play()

beat_start = sa.WaveObject.from_wave_file(...)
beat_end = sa.WaveObject.from_wave_file(...)

bpm = 60.0
bps = bpm / 60
reactor.callLater(0 / bps, beat, bpm / 4, beat_start)
reactor.callLater(1 / bps, beat, bpm / 4, beat_start)
reactor.callLater(2 / bps, beat, bpm / 4, beat_start)
reactor.callLater(3 / bps, beat, bpm / 4, beat_end)
reactor.run()

可能值得注意的是,我已经删除了
wait\u done
调用。如果您像那样阻塞reactor线程,那么基于时间的事件的调度就不那么可靠了。

下面是另一个解决方案

import simpleaudio as sa
from twisted.internet import task
from twisted.internet import reactor

def beat(bpm, wave_obj):
    timeout = 60.0 / bpm
    l = task.LoopingCall(play_beat, wave_obj)
    l.start(timeout)

def play_beat(wave_obj):
    wave_obj.play()

beat_start = sa.WaveObject.from_wave_file(...)
beat_end = sa.WaveObject.from_wave_file(...)

bpm = 60.0
bps = bpm / 60
reactor.callLater(0 / bps, beat, bpm / 4, beat_start)
reactor.callLater(1 / bps, beat, bpm / 4, beat_start)
reactor.callLater(2 / bps, beat, bpm / 4, beat_start)
reactor.callLater(3 / bps, beat, bpm / 4, beat_end)
reactor.run()

可能值得注意的是,我已经删除了
wait\u done
调用。如果您像那样阻塞reactor线程,那么基于时间的事件的调度就不那么可靠。

当您说它不工作时,这意味着什么?它会抛出错误吗?它是否以意外的方式工作?啊,对不起。变量计数器始终从1开始。例如,在函数“play_beat(counter)”中:如果在counter+=1之后生成打印语句,则始终为2。但是我希望它应该是3,比4,比5,比6等等。这并不奇怪,你用参数
counter=counter
beat()
调用它,并且你在
beat()
范围内从不更新
counter
<代码>计数器不是全局变量。哦,我太笨了xD谢谢,它与全局变量一起工作!我的评论意在指出错误,而不是建议如何修复它。请看一看。在这种情况下,Jean-Paul Calderones的解决方案要好得多。当你说它不起作用时,这是什么意思?它会抛出错误吗?它是否以意外的方式工作?啊,对不起。变量计数器始终从1开始。例如,在函数“play_beat(counter)”中:如果在counter+=1之后生成打印语句,则始终为2。但是我希望它应该是3,比4,比5,比6等等。这并不奇怪,你用参数
counter=counter
beat()
调用它,并且你在
beat()
范围内从不更新
counter
<代码>计数器不是全局变量。哦,我太笨了xD谢谢,它与全局变量一起工作!我的评论意在指出错误,而不是建议如何修复它。请看一看。在这种情况下,Jean-Paul Calderones的解决方案要好得多。