簡體   English   中英

PyGame 在重新連接時重新初始化 USB MIDI 設備

[英]PyGame Re-Initialize USB MIDI Device on Reconnect

我正在使用 PyGame 讀取 USB MIDI 設備,與 此處使用的非常相似,只是我將它作為 Raspberry Pi 上的后台服務運行。

我希望能夠斷開並重新連接 MIDI 設備,並且仍然能夠讀取它。

我嘗試了兩種方法:

  1. 使用 pygame.midi.get_count() 和 info() 定期枚舉 MIDI 設備。
  2. 使用 pyudev 監控 USB 事件,類似於這個例子。

(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM