我最近一直在探索macOS和Windows上可用的MIDI API(分别是Core MIDI和Windows Multimedia(,并注意到:
在MacOS上,查询可用源的数量后,可以通过检查属性kMIDIPropertyUniqueID
的值来唯一地标识每个源。
在Win32上,我找不到一个明确的替代方案——似乎输入设备的";ID";只不过是已连接设备列表的索引,随着新设备的连接和断开,该列表随时可能发生变化。可以从设备请求的功能结构中的信息也没有特别的区别,因为同时使用两个相同的MIDI键盘会导致两个完全相同的功能集,直到产品名称。
是否有某种方法可以在WinMM中唯一识别这些设备?
简短的回答是否。
WinMM中的设备ID实际上只是设备列表中的一个索引。因此,如果你拔掉一个设备的插头,再插入另一个具有相同属性(例如名称(的设备,你将无法确定使用的设备是旧设备还是新设备。当然,名称可以是相同的,所以这不是一个选项。
因此,从编程的角度来看,无法区分Windows中具有相同属性的两个MIDI设备。在应用程序中,您可以提供一个类似";刷新设备";或";测试装置";以便与当前设备保持同步,并能够确定GUI中的哪个对象对应于MIDI设备。
至于macOS,kMIDIPropertyUniqueID
是一个选项,但也有细微差别。来自于关于常量的文档:
系统为所有对象分配唯一的ID。您可以设置虚拟端点上的属性;但是,如果ID不是唯一的。
因此,在某些情况下,您可以获得非唯一值。在我看来,在macOS中识别设备最可靠的方法是使用其参考。例如,当您获得一个具有MIDIGetSource
的源设备时,结果是MIDIEndpointRef
。事实上,它是一个UInt32
数字,在系统范围内是真正唯一的。
因此,我在我的.NET库DryWetMDI中依靠MIDIEndpointRef
来区分macOS中的MIDI设备。此外,还可以提供MIDI设备观看(添加/删除(。但不幸的是,对于Windows来说,这是不可能的。
不幸的是,在WinMM中没有等效的。
你能做的最好的事情是打开设备以获得它的句柄。句柄将是唯一的,并且将始终引用打开的设备,即使添加和删除了其他设备。
一旦有了句柄,就可以使用midiInGetID()
或midiOutGetID()
来获取ID,以防ID发生更改。