[英]PyGame Re-Initialize USB MIDI Device on Reconnect
我正在使用 PyGame 读取 USB MIDI 设备,与 此处使用的非常相似,只是我将它作为 Raspberry Pi 上的后台服务运行。
我希望能够断开并重新连接 MIDI 设备,并且仍然能够读取它。
我尝试了两种方法:
(1) 的问题在于 pygame.midi 似乎总是返回相同的值(get_count 和 info),无论设备是否仍然连接。
(2) 的问题在于它永远不会调用我为事件注册的异步函数(尽管独立示例工作正常,只是将子系统更改为 USB)。 我认为这可能是线程的问题,所以我调用了所有内容来注册来自专用线程的事件,然后运行 glib.MainLoop.run() 进行空闲等待,但发现 pygame 无法读取 midi 设备如果我在运行我的 AMK 类之前启动了任何线程,即使只是一个打印内容并返回的线程。 (我正在使用 glib,因为 Pi 存储库中的 pyudev 版本是 0.13,但我猜更新的方式是 gobject 等效的)。
因此我求助于使用 udevd 来检测连接事件并通过 /etc/udev/rules.d/ 触发器重新启动我的服务,它工作正常,但很笨拙,并且丢失了我的脚本中的状态(我想保存)。
所以,在我浪费更多时间调试之前(2),我希望有人能指出我正确的方向。
pygame 使用 PortMidi,它最初是为 Windows MIDI API 设计的,并假设 MIDI 端口集永远不会改变。
您必须使用一个单独的监视器进程,它会在 MIDI 端口发生变化时重新启动您的程序。
我还没有对此进行彻底的测试,但我相信如果你调用quit
然后再次调用init
,你可以得到一个正确更新的 MIDI 设备列表。 下面是一个例子:
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()
这就是我监视现有或新添加的 Midi 设备的方式 - wait_for_midi()
将阻塞,直到系统中出现 MIDI 设备并将/dev/midi*
路径返回给它。
import re
import pyudev
def is_midi_device(dev_path):
if dev_path is None:
return False
if re.match(u"^/dev/midi[0-9]+$", dev_path):
return True
return False
# Return path to a MIDI device when found.
def wait_for_midi():
context = pyudev.Context()
# Check for existing midi devices
for device in context.list_devices():
dev_path = device.device_node
if is_midi_device(dev_path) :
print('Found {}'.format(dev_path))
return dev_path
# Monitor for new midi devices as added
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='sound')
for action, device in monitor:
if action != "add":
continue
dev_path = device.device_node
if is_midi_device(dev_path) :
print('Just added: {}'.format(dev_path))
return dev_path
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.