用Python创建和Qt准确的节拍器(Creating an accurate metronome

2019-07-30 03:12发布

I'm trying to add a simple metronome to my cross-platform pyQt program, but having a lot of difficulty getting accurate timing. Playing the sound seems to work the best using PyGame's sound system. I tried Phonon, but it just wasn't consistent at all and QSound doesn't work at all on my system. I've tried handling timing with python's time library and using QTimers, but QTimeLine seems to work the best.

The timing at lower tempo is not too bad... still a hiccup here and there. Higher tempos are not accurate at all however.

Any ideas/suggestions would be greatly appreciated!

Here's some code:

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()

Answer 1:

我不是很熟悉Python和Qt的互动,但我确实有计时器和线程和Qt的经验。

一般时序限制

Qt中的定时通常为图形动画制作。 在Qt的定时器文档,它说,计时器精确到约15毫秒,但它取决于平台。 在Windows中,如果你通过自己的阅读文档上的定时器和系统时钟,它说他们是精确到约11至16毫秒。

线程优先级

此外线程的优先级会影响你的节拍器的结果。 你或许应该看看你的线程的优先级设置为时间关键(见QThread::Priority ),从而使系统为您提供更好的时机,然后告诉你的函数做一个睡眠(0)或yieldCurrentThread()调用完成后玩你的声音。

QObject的连接呼叫

连接呼叫在Qt的使用做了Qt::AutoConnection ,这意味着Qt的决定是否使用该事件队列,或者使用直接调用连接。 对于定时,直接呼叫是优选的。

另外,不要在processEvents播放声音或者根本没有后打电话。 这样做事先告诉Qt你想达到你的下一个呼叫之前得到处理的任何其他事物坐在事件队列。 检查出的文档QT事件系统 。

MIDI文件

大多数游戏产生的声音,我知道的使用MIDI文件完成的。 他们是微小的,他们的声音回路的渲染是在很多平台上相当一致。 也许你可以拉断的东西选择的100个MIDI文件之一。 还有一些项目有像ScaleTempo ,但似乎这是一种旧的(最后更新于2008年)。

希望帮助。

免责声明:大部分我张贴的链接都来自Qt的5.我在的Qt 4.7开始编程居多,但没有安排就我所知改造Qt的5(主要是动画后端优化)的定时器和事件系统。



文章来源: Creating an accurate metronome with python and Qt