使用python和Qt创建精确的节拍器

使用python和Qt创建精确的节拍器,python,qt,audio,pyqt,pygame,Python,Qt,Audio,Pyqt,Pygame,我正试图在我的跨平台pyQt程序中添加一个简单的节拍器,但要获得准确的计时有很多困难。使用PyGame的声音系统播放声音似乎效果最好。我试过声子,但它根本不一致,而且QSound在我的系统上根本不起作用。我曾尝试使用python的时间库和qtimer处理计时,但QTimeLine似乎工作得最好 节奏较低的时机还不错。。。还是有点打嗝。然而,更高的节奏并不准确 如有任何想法/建议,将不胜感激 下面是一些代码: class Metronome(object): def init_metron

我正试图在我的跨平台pyQt程序中添加一个简单的节拍器,但要获得准确的计时有很多困难。使用PyGame的声音系统播放声音似乎效果最好。我试过声子,但它根本不一致,而且QSound在我的系统上根本不起作用。我曾尝试使用python的时间库和qtimer处理计时,但QTimeLine似乎工作得最好

节奏较低的时机还不错。。。还是有点打嗝。然而,更高的节奏并不准确

如有任何想法/建议,将不胜感激

下面是一些代码:

class Metronome(object):
    def init_metronome(self):
        self.metronome_timer = QtCore.QTimeLine(100000)
        self.metronome_timer.valueChanged.connect(self.tick)
        self.metronome_timer.setCurveShape(3) #linear curve

        self.ui.pushButton_metronome.toggled.connect(self.toggle_metronome)
        self.ui.spinBox_metronome_bpm.valueChanged.connect(self.set_metronome_bpm)

        pygame.mixer.init()
        self.sound = pygame.mixer.Sound("./sounds/tick.wav")


    def toggle_metronome(self):
        if self.ui.pushButton_metronome.isChecked() == True:
            self.set_metronome_bpm()
            self.metronome_timer.start()
        else: 
            self.metronome_timer.stop()

    def set_metronome_bpm(self):
        bpm = self.ui.spinBox_metronome_bpm.value()
        self.metronome_timer.setUpdateInterval(60./bpm * 1000)

    def tick(self):
        QtCore.QCoreApplication.processEvents()
        self.sound.play()

我不太熟悉Python和Qt的交互,但我确实有使用计时器、线程和Qt的经验

一般时间限制 Qt中的计时通常用于图形动画。在文档中,它说计时器精确到15毫秒左右,但这取决于平台。在windows中,如果你通读它们的on定时器和系统时钟,就会发现它们精确到11到16毫秒

线程优先级 线程的优先级也会影响节拍器的结果。您可能应该考虑将线程的优先级设置为时间关键型(请参阅),以便系统为您提供更好的计时,然后告诉您的函数在播放完声音后执行睡眠(0)或调用

QObject连接调用 Qt中的Connect调用是使用完成的,这意味着Qt决定是使用事件队列还是使用直接调用进行连接。对于计时,最好是直接呼叫

另外,播放声音后是否调用processEvents。事先这样做告诉Qt,您希望在到达下一个调用之前处理事件队列中的任何其他内容。请查看上的文档

MIDI文件 据我所知,游戏中生成的大部分声音都是使用MIDI文件完成的。它们很小,在许多平台上,声音循环的呈现都非常一致。也许你可以从100个midi文件中选择一个。也有像这样的项目,但似乎有点旧(上次更新于2008年)

希望有帮助


免责声明:我发布的大多数链接都来自Qt5。我主要是在Qt 4.7中编程的,但据我所知,定时器和事件系统并没有计划在Qt 5中进行改造(主要是动画后端优化)。

非常感谢您提供的好信息。我最终选择了懒惰的方式,使用了多个MIDI文件。我只需选择一个速度,加载相应的midi文件,然后在无限循环中播放。编程更简单,而且midi文件非常小,它们占用的额外空间可以忽略不计。在各种机器/平台上,它也可能更加一致。