Swift中如何利用MIDIInputPortCreateWithProtocol的srcConnRefCon区分多MIDI设备
区分CoreMIDI中多个BLE MIDI设备的正确方式
核心问题分析
你当前的代码错误在于在接收回调里执行了MIDIPortConnectSource操作——这个函数是用来建立端口和MIDI源的连接的,应该在初始化阶段调用,而不是收到MIDI数据时。另外,你对srcConnRefCon的类型转换逻辑有误,导致无法正确获取到对应的MIDI设备端点(MIDIEndpointRef)。
正确实现步骤
要通过srcConnRefCon区分设备,关键是在连接MIDI源时,将该源的MIDIEndpointRef作为自定义引用传递给MIDIPortConnectSource,之后在接收回调里直接还原这个引用即可。
1. 创建MIDI输入端口
首先创建输入端口,回调里只需要处理数据和解析srcConnRefCon:
var inputPort: MIDIPortRef = 0 let createStatus = MIDIInputPortCreateWithProtocol( client, "MidiMonitor Input Port" as CFString, MIDIProtocolID._1_0, &inputPort ) { midiEventList, srcConnRefCon in // 解析MIDI数据 let eventPacket = midiEventList.pointee.packet let timeStamp = eventPacket.timeStamp let midiData = eventPacket.words.0 // 从srcConnRefCon还原MIDIEndpointRef guard let srcRefPtr = srcConnRefCon else { return } let sourceEndpoint = srcRefPtr.load(as: MIDIEndpointRef.self) // 获取设备名称 let displayName = self.getDisplayName(sourceEndpoint) print("MIDI Received From Source: \(displayName)") // 传递数据给代理 self.delegate?.didReceiveMidiData( midiEventPacket: eventPacket, timeStamp: timeStamp, midiData: midiData, srcConnRefCon: sourceEndpoint ) } guard createStatus == noErr else { print("Failed to create MIDI input port: \(createStatus)") return }
2. 连接所有可用的MIDI源(包括BLE设备)
在初始化阶段(比如设备连接成功后),遍历所有MIDI输入源,将每个源的MIDIEndpointRef作为refCon传入连接函数:
func connectAllMIDISources() { let sourceCount = MIDIGetNumberOfSources() for index in 0..<sourceCount { let sourceEndpoint = MIDIGetSource(index) var endpointPtr = UnsafeMutableRawPointer(bitPattern: Int(sourceEndpoint)) let connectStatus = MIDIPortConnectSource( inputPort, sourceEndpoint, endpointPtr ) if connectStatus == noErr { print("Connected to MIDI source: \(getDisplayName(sourceEndpoint))") } else { print("Failed to connect to source: \(connectStatus)") } } } // 辅助函数:获取设备显示名称 func getDisplayName(_ endpoint: MIDIEndpointRef) -> String { var name: Unmanaged<CFString>? MIDIObjectGetStringProperty(endpoint, kMIDIPropertyDisplayName, &name) return name?.takeRetainedValue() as String? ?? "Unknown Device" }
错误码解释
你之前看到的错误码对应含义:
-50:参数错误(你在回调里使用了无效的MIDIEndpointRef调用MIDIPortConnectSource)-10832(kMIDIErrorAlreadyConnected):端口已经和该源建立过连接,重复调用导致错误
关键注意事项
- 当BLE MIDI设备连接/断开时,需要监听
MIDINotification,及时调用MIDIPortConnectSource或MIDIPortDisconnectSource更新连接状态 srcConnRefCon是你在连接时传入的自定义指针,必须保证其指向的对象在回调执行期间有效(这里用MIDIEndpointRef是安全的,因为它是CoreMIDI管理的引用)
内容的提问来源于stack exchange,提问作者Suruthika Balaji
相关产品推荐
相关产品推荐

