[英]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.