Search code examples
python-2.7sliderwxpythonpygamemidi

Pygame midi prevents other input


I wish to have real-time midi input, in order to control some wx.Sliders. I have been able to achieve this, however it prevents interaction with the sliders via the mouse or keyboard and causes the application to crash.

This is the code I have at the moment.

import wx, pygame, pygame.midi

class windowClass(wx.Frame):
    def __init__(self, *args, **kwargs): 
        super(windowClass, self).__init__(*args, **kwargs) 
        self.basicGUI()

    def basicGUI(self):
        panel = wx.Panel(self) 
        self.slider = wx.Slider(panel, -1, 2, 0, 128, pos=(10,25), size=(250,-1), style=wx.SL_AUTOTICKS | wx.SL_LABELS)
        sliderText = wx.StaticText(panel, -1, 'Slider 1 ', (8,8))
        self.slider2 = wx.Slider(panel, -1, 2, 0, 128, pos=(10,110), size=(250,-1), style=wx.SL_AUTOTICKS | wx.SL_LABELS)
        sliderText = wx.StaticText(panel, -1, 'Slider 2', (8,88))
        self.Bind(wx.EVT_SLIDER, self.sliderUpdate)
        self.SetTitle('Sliders Window!')
        self.Show(True)

        pygame.init()
        pygame.midi.init()
        inp = pygame.midi.Input(1)
        running = True
        while running:
            if inp.poll():
                dataset = inp.read(1)
                control = dataset[0][0][1]
                if control > 8:
                    continue
                if control == 1:
                    value = dataset[0][0][2]
                    self.slider.SetValue(value)
                if control == 2:
                    value = dataset[0][0][2]
                    self.slider2.SetValue(value)
            pygame.time.wait(10)

    def sliderUpdate(self, event):
        value1 = self.slider1.GetValue()
        value2 = self.slider2.GetValue()
        print value1, value2

def main():
    app = wx.App()
    windowClass(None)
    app.MainLoop()

main()

What is causing pygame.midi to take all resources? I have a feeling it is regarding while running = True, however my attempts at trying to close the instance don't seem to work.

How can I have the sliders being controlled by the midi and the mouse calling sliderUpdate? Thanks for any help.


Solution

  • You have a loop that never exits, so your program never reaches the parts that deal with anything except the midi input

    I would move the code that is currently in that loop into a function, remove the loop, and add a timer to the panel, e.g.

    def basicGUI(self):
        ... panel stuff
    
        pygame.init()
        pygame.midi.init()
        timer = wx.Timer(self, -1)
        self.Bind(wx.EVT_TIMER, self.OnTimer)
        timer.Start(10, False)
    
    def OnTimer(self, event):
        inp = pygame.midi.Input(1)
        if inp.poll():
            dataset = inp.read(1)
            control = dataset[0][0][1]
            if control > 8:
                continue
            if control == 1:
                value = dataset[0][0][2]
                self.slider.SetValue(value)
            if control == 2:
                value = dataset[0][0][2]
                self.slider2.SetValue(value)