I'm using CoreMIDI to receive messages from a MIDI-Keyboard via Camera Connection Kit on iOS-Devices. My App is about pitch recognition. I want the following functionality to be automatic:
By default use the microphone (already implemented), if a MIDI-Keyboard is connected use that instead.
I could find out how to tell if it is a USB-Keyboard using the default driver. Just ask for the device called "USB-MIDI":
private func getUSBDeviceReference() -> MIDIDeviceRef? {
for index in 0..<MIDIGetNumberOfDevices() {
let device = MIDIGetDevice(index)
var name : Unmanaged<CFString>?
MIDIObjectGetStringProperty(device, kMIDIPropertyName, &name)
if name!.takeRetainedValue() as String == "USB-MIDI" {
return device
}
}
return nil
}
But unfortunately there are USB-Keyboards that use a custom driver. How can I tell if I'm looking at one of these? Standard Bluetooth- and Network-Devices seem to be always online. Even if Wifi and Bluetooth are turned off on the device (strange?).
I ended up using the USBLocationID
. It worked with any device I tested so far and none of the users complained.But I don't expect many users to use the MIDI-Features of my app.
/// Filters all `MIDIDeviceRef`'s for USB-Devices
private func getUSBDeviceReferences() -> [MIDIDeviceRef] {
var devices = [MIDIDeviceRef]()
for index in 0..<MIDIGetNumberOfDevices() {
let device = MIDIGetDevice(index)
var list: Unmanaged<CFPropertyList>?
MIDIObjectGetProperties(device, &list, true)
if let list = list {
let dict = list.takeRetainedValue() as! NSDictionary
if dict["USBLocationID"] != nil {
devices.append(device)
}
}
}
return devices
}