Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyGame Re-Initialize USB MIDI Device on Reconnect

I'm using PyGame to read a USB MIDI device, very similar to what is used here, except I run it as a background service on a Raspberry Pi.

I would like to be able to disconnect and reconnect the MIDI device, and still be able to read it.

I have tried two approaches:

  1. Regularly enumerate the MIDI devices using pygame.midi.get_count() and info().
  2. Use pyudev to monitor USB events, similar to this example.

The problem with (1) is that it seems that pygame.midi always returns the same values (both get_count and info), regardless of whether the device is still connected.

The problem with (2) is that it would never call the asynchronous function I registered for events (though the standalone example works fine, just changing the subsytem to usb). I figured this might be a problem with threading, so I called everything to register for events from a dedicated thread, which then ran glib.MainLoop.run() to idle wait, but discovered the pygame would not be able to read the midi device if I started any thread before running my AMK class, even just a thread that printed something and returned. (I'm using glib since the version of pyudev in the Pi repo is 0.13, but I guess the newer way is the gobject equivalent).

Thus I resorted to using udevd to detect the connect event and restart my service via a /etc/udev/rules.d/ trigger, which works okay, but is kludgy, and loses the state in my script (which I would like to save).

So, before I waste many more hours debugging (2), I was hoping someone could perhaps point me in the right direction.

like image 831
cwshep Avatar asked Dec 11 '25 11:12

cwshep


2 Answers

pygame uses PortMidi, which was originally designed for the Windows MIDI API and assumes that the set of MIDI ports never changes.

You have to use a separate monitor process that restarts your program whenever MIDI ports change.

like image 77
CL. Avatar answered Dec 14 '25 01:12

CL.


I haven't tested this thoroughly yet but I believe that if you call quit and then again init, you can then get a properly updated list of MIDI devices. Here is an example:

import pygame, pygame.midi    
pygame.midi.init()    
print pygame.midi.get_count()    
a=raw_input('Connect or disconnect some MIDI devices')    
pygame.midi.quit()    
pygame.midi.init()
print pygame.midi.get_count()
like image 44
Hector Socas-Navarro Avatar answered Dec 13 '25 23:12

Hector Socas-Navarro



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!