CoreMIDI iOS some notes are missing / skipped / not read

60 Views Asked by At

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)

0

There are 0 best solutions below