0

I'm using Pygame midi to create a piano.

Example:

player.note_on(60, 127)
pygame.time.delay(1000)
player.note_off(60, 127)

To be able to actually hear the note pygame.time.delay() is necessary.

The problem is that sometimes I want to be able to tap the button again before time.delay() is finished. Currently if i try to tap the button again before time.delay() is finsihed nothing happens and i have to wait for it to finish.

How can i make it so that no matter when i press the note it will play without me having to wait for time.delay to finish the previous note?? Again the time delay is necessary to be able to hear a note.

I'm using Pygame for midi and PyQt5 for the application.

Here is my actual code:

from PyQt5 import QtCore, QtGui, QtWidgets
import pygame
import pygame.midi
import time

pygame.midi.init()
player = pygame.midi.Output(0)
player.set_instrument(1)


        'THIS IS JUST SETTING UP PYQT5 AND NOT RELATED TO QUESTION'
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(998, 759)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(430, 80, 121, 71))
        self.pushButton.setObjectName("pushButton")


        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 998, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        'THIS IS THE BUTTON THAT CALLS MY FUNCTION'
        self.pushButton.clicked.connect(clicked)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "C"))




'HERE IS MY FUNCTION WITH THE TIME DELAY'
def clicked():
    global player

    print('clicked')
    player.note_on(60, 127)
    pygame.time.delay(1000)
    player.note_off(60, 127)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Greg James
  • 15
  • 4
  • 2
    You are going to need to set up a genuine real-time event loop, with a delay of like 10ms per loop. When a note is pressed, you'll do the note_on, and set a timeout counter for 1 second from now.. During each loop, check for new keyboard events and check for timeout. – Tim Roberts Apr 01 '21 at 21:46
  • I have just spent some time looking into this but can't figure out quite how to implement it. I have tried asyncio but i can't seem to figure it out. any ideas on how to do this? – Greg James Apr 02 '21 at 02:22
  • I think you can use a `QtTimer` for this. Setup a `QtTimer` on a 100ms recall. In the timer handler, check to see if you're in the middle of a countdown. When the countdown expires, stop the note. – Tim Roberts Apr 02 '21 at 04:32
  • I think the problem might be that when i click the button and it calls the function `clicked()` that i then cannot press the button again until that function `clicked()` is complete, so it doesnt matter if i check every 100ms for the button being clicked because it will never be clicked until that function is complete? Meaning even if i set up a loop to check to see if the note is pressed it will never be registered as pressed because we're still in the original function the button has called?not sure how to get the button click to register while still inside the function the click called – Greg James Apr 02 '21 at 18:03

0 Answers0