When pressing keys simultaneously (I experienced from 3 to 10 keys together ) , on Mac desktop using a piano connected via Bluetooth, it misses some notes. Maybe it is reproducible in iOS too but I haven't tried that out.
I am pretty sure it's a bug in with my Swift code because I used Midi monitor on the same mac simultaneously and Midi monitor finds all the note https://www.snoize.com/midimonitor/ but not CoreMIDI.
I also tried with a USB cable and with USB midi, but I can't reproduce.
Here is the Swift Code:
var client = MIDIClientRef()
var inputPort = MIDIPortRef()
MIDIClientCreate("MIDI Input Client" as CFString, nil, nil, &client)
MIDIInputPortCreate(client, "MIDI Input Port" as CFString, { (packetListPointer,_, _) in
let packets = packetListPointer.pointee
var packet = packets.packet
for _ in 0 ..< packets.numPackets {
let bytes = Mirror(reflecting: packet.data).children.map { $0.value }
// print("Received MIDI message: \(bytes)")
// Extract the relevant bytes from the MIDI message
let statusByte = Int(bytes[0] as! UInt8) // The status byte contains the message type
let noteByte = Int(bytes[1] as! UInt8)// The note byte contains the MIDI note number
// Check if the message is a note on or note off message
let isNoteOn = (statusByte & 0xF0) == 0x90 // The status byte for a note on message starts with 0x90
let isNoteOff = (statusByte & 0xF0) == 0x80 // The status byte for a note off message starts with 0x80
if isNoteOn || isNoteOff {
let noteNumber = Int(noteByte) // Convert the note byte to an integer
let noteName = NoteName(forNoteNumber: noteNumber)
let octave = noteNumber / 12 - 1 // Divide the note number by 12 and subtract 1 to get the octave
let direction = isNoteOn ? "up" : "down" // If it's a note on message, the direction is "up". If it's a note off message, the direction is "down"
print("Note: \(noteName)\(octave) \(direction)")
}
packet = MIDIPacketNext(&packet).pointee
}
}, nil, &inputPort)
// Set up the MIDI input endpoint and connect it to the input port
let sourceCount = MIDIGetNumberOfSources()
for i in 0..<sourceCount {
let src = MIDIGetSource(i)
MIDIPortConnectSource(inputPort, src, nil)
}
func NoteName(forNoteNumber noteNumber: Int) -> String {
let noteNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
let noteIndex = noteNumber % 12
return noteNames[noteIndex]
}
And this prints:
Note: B3 up
Note: A3 up
Note: E3 up
Note: G3 up
Note: F3 up
Note: E4 up
Note: F4 up
Note: D4 up
Note: G3 down
Note: A3 down
Note: F3 down
Note: E3 down
Note: B3 down
Note: D4 down
Note: E4 down
Note: C4 down
Note: G4 down
Note: F4 down
But the Midi Monitor prints:
19:58:58.510 From MIDI Piano Bluetooth Note On 1 B2 45
19:58:58.536 From MIDI Piano Bluetooth Note On 1 A2 70
19:58:58.536 From MIDI Piano Bluetooth Note On 1 E2 64
19:58:58.536 From MIDI Piano Bluetooth Note On 1 G2 70
19:58:58.536 From MIDI Piano Bluetooth Note On 1 F2 80
19:58:58.536 From MIDI Piano Bluetooth Note On 1 C3 43 <- missing
19:58:58.538 From MIDI Piano Bluetooth Note On 1 E3 64
19:58:58.538 From MIDI Piano Bluetooth Note On 1 F3 45 <- missing
19:58:58.538 From MIDI Piano Bluetooth Note On 1 G3 43
19:58:58.539 From MIDI Piano Bluetooth Note On 1 D3 47
19:58:58.780 From MIDI Piano Bluetooth Note Off 1 G2 0
19:58:58.807 From MIDI Piano Bluetooth Note Off 1 A2 0
19:58:58.807 From MIDI Piano Bluetooth Note Off 1 F2 0
19:58:58.807 From MIDI Piano Bluetooth Note Off 1 E2 0
19:58:58.807 From MIDI Piano Bluetooth Note Off 1 B2 0
19:58:58.808 From MIDI Piano Bluetooth Note Off 1 D3 0
19:58:58.808 From MIDI Piano Bluetooth Note Off 1 E3 0
19:58:58.817 From MIDI Piano Bluetooth Note Off 1 C3 0
19:58:58.817 From MIDI Piano Bluetooth Note Off 1 G3 0
19:58:58.818 From MIDI Piano Bluetooth Note Off 1 F3 0
(please ignore the octave shift of one)