Watch all six MIDI links from the checklist, including ProPresenter -> Lighting
Adds Tracks -> Livebox, Tracks -> Studio B and ProPresenter -> Lighting
(read on the ProPresenter Mac over SSH), each with the hold-to-reconnect fix.
coremidi.py now recognises the network MIDI driver on macOS 26.2 too
("AppleMIDIRTPDriver"; 26.5 calls it "AppleMIDINetworkDriver"), which is why
the ProPresenter Mac's session looked empty before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+14
-18
@@ -54,6 +54,10 @@ _cf.CFPropertyListCreateWithData.restype = ctypes.c_void_p
|
||||
_cf.CFPropertyListCreateWithData.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_ulong,
|
||||
ctypes.c_void_p, ctypes.c_void_p]
|
||||
|
||||
# Apple's network MIDI driver: "AppleMIDIRTPDriver" on macOS 26.2 (ProPresenter Mac),
|
||||
# "AppleMIDINetworkDriver" on 26.5 (NA Ingest, NA Tracks).
|
||||
NETWORK_DRIVERS = ("com.apple.AppleMIDINetworkDriver", "com.apple.AppleMIDIRTPDriver")
|
||||
|
||||
# One lock around every CoreMIDI call: concurrent first calls from two threads
|
||||
# (session reads vs. MIDIClientCreate) intermittently fail with -2.
|
||||
_lock = threading.RLock()
|
||||
@@ -109,7 +113,7 @@ def _session_entities():
|
||||
out = []
|
||||
for i in range(_cm.MIDIGetNumberOfDevices()):
|
||||
dev = _cm.MIDIGetDevice(i)
|
||||
if _string_prop(dev, "driver") != "com.apple.AppleMIDINetworkDriver":
|
||||
if _string_prop(dev, "driver") not in NETWORK_DRIVERS:
|
||||
continue
|
||||
for j in range(_cm.MIDIDeviceGetNumberOfEntities(dev)):
|
||||
ent = _cm.MIDIDeviceGetEntity(dev, j)
|
||||
@@ -151,23 +155,15 @@ def sessions():
|
||||
"""{session name: {"port": int, "peers": [{"name", "address", "state"}]}}"""
|
||||
found = {}
|
||||
with _lock:
|
||||
for i in range(_cm.MIDIGetNumberOfDevices()):
|
||||
dev = _cm.MIDIGetDevice(i)
|
||||
if _string_prop(dev, "driver") != "com.apple.AppleMIDINetworkDriver":
|
||||
continue
|
||||
for j in range(_cm.MIDIDeviceGetNumberOfEntities(dev)):
|
||||
ent = _cm.MIDIDeviceGetEntity(dev, j)
|
||||
sess = _dict_prop(ent, "apple.midirtp.session")
|
||||
if sess is None:
|
||||
continue
|
||||
name = sess.get("dns-sd-name") or _string_prop(ent, "name") or "?"
|
||||
found[name] = {
|
||||
"port": sess.get("port"),
|
||||
"peers": [
|
||||
{"name": p.get("name", ""), "address": p.get("address", ""), "state": p.get("state", "")}
|
||||
for p in sess.get("peers", [])
|
||||
],
|
||||
}
|
||||
for ent, sess in _session_entities():
|
||||
name = sess.get("dns-sd-name") or _string_prop(ent, "name") or "?"
|
||||
found[name] = {
|
||||
"port": sess.get("port"),
|
||||
"peers": [
|
||||
{"name": p.get("name", ""), "address": p.get("address", ""), "state": p.get("state", "")}
|
||||
for p in sess.get("peers", [])
|
||||
],
|
||||
}
|
||||
return found
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user