yun
yun

Reputation: 1283

iOS CoreMIDI Skipping MidiPackets

I'm having issues with implementing MIDI into my iOS app as the receiver callback seems to be skipping MIDI messages and packets. I'm using Midi Monitor to check what MIDI messages I'm missing, skipping over, etc.

So the million dollar question is why is iOS skipping certain MIDI messages? Sometimes it doesn't skip MIDI messages, but other times it does. I'm not sure how to approach debugging this as I have exhausted my brain at this point.

My receiver code:

void MidiReceiver(const MIDIPacketList *packets, 
                  void *context, void *sourceContext) {
    dispatch_async(dispatch_get_main_queue(), ^{
    if (packets->numPackets > 0) {
        MIDIPacket *packet = (MIDIPacket *)packets->packet;

        // Loop through total number of packets
        for (int i = 0; i < packets->numPackets; i++) {
            // Go through each packet, iOS sometimes clumps all data into one packet
            // if the MIDI messages are triggered at the same time
            for (int j = 0; j < packet->length; j += 3) {
                NSArray *array = [[NSArray alloc] initWithObjects:[NSNumber numberWithUnsignedInt:packet->data[j]],
                                  [NSNumber numberWithUnsignedInt:packet->data[j+1]],
                                  [NSNumber numberWithUnsignedInt:packet->data[j+2]], nil];

                // Use the data to create do meaningful in the app
                [myViewController processMidiData:array];
            }

            // Next packet
            packet = MIDIPacketNext(packet);
        }
    }
});

The monitor code format is : (TIME) - (MIDI Command Type) - (CC Val or Velocity)

Midi Monitor Debug:

12:45:32.697    Control 0
12:45:32.720    Control 1
12:45:32.737    Control 1
12:45:32.740    Control 2
12:45:32.750    Control 3
12:45:32.763    Note Off    A♯1 0
12:45:32.763    Note Off    F2  0
12:45:32.763    Note Off    D3  0
12:45:32.763    Control 4
12:45:32.770    Control 5
12:45:32.780    Control 6
12:45:32.790    Control 8
12:45:32.800    Control 9
12:45:32.810    Control 11
12:45:32.820    Control 13
12:45:32.832    Control 14
12:45:32.845    Control 16
12:45:32.850    Control 18
12:45:32.873    Control 21
12:45:32.883    Control 22
12:45:32.898    Control 24
12:45:32.913    Control 26
12:45:32.933    Control 27
12:45:32.948    Control 28
12:45:33.020    Control 27
12:45:33.030    Control 26
12:45:33.040    Control 25
12:45:33.050    Control 24
12:45:33.060    Control 22

My App's Debug Monitor:

12:45:33.050    Control 0
12:45:33.051    Control 1
12:45:33.051    Control 1
12:45:33.051    Control 2
12:45:33.051    Control 3
12:45:33.083    Note Off    D3 0       <----- Where's A#1 and F2!!! :(
12:45:33.087    Control 4
12:45:33.087    Control 4
12:45:33.097    Control 5
12:45:33.100    Control 6
12:45:33.110    Control 8
12:45:33.120    Control 9
12:45:33.130    Control 11
12:45:33.140    Control 13
12:45:33.153    Control 14
12:45:33.165    Control 16
12:45:33.170    Control 18
12:45:33.193    Control 21
12:45:33.203    Control 22
12:45:33.218    Control 24
12:45:33.233    Control 26
12:45:33.256    Control 27
12:45:33.268    Control 28
12:45:33.341    Control 27
12:45:33.351    Control 26
12:45:33.361    Control 25
12:45:33.374    Control 24
12:45:33.381    Control 22

Upvotes: 1

Views: 166

Answers (1)

yun
yun

Reputation: 1283

Got some help from Kurt Revis and it seemed like I was sending the packets too late due to my usage of dispatch_async.

My revised code (I parsed the packets first):

void MidiReceiver(const MIDIPacketList *packets, 
              void *context, void *sourceContext) {

    NSMutableArray *packetData = [[NSMutableArray alloc] init];

    if (packets->numPackets > 0 && object != nil) {
        MIDIPacket *packet = &packets->packet[0];
        // Loop through total number of packets
        for (int i = 0; i < packets->numPackets; ++i) {
             int idx = 0;
             while (idx < packet->length) {
                 NSArray *array = [[NSArray alloc] initWithObjects:[NSNumber numberWithUnsignedInt:packet->data[idx]],
                                  [NSNumber numberWithUnsignedInt:packet->data[idx+1]],
                                  [NSNumber numberWithUnsignedInt:packet->data[idx+2]], nil];

                [packetData addObject:array];
                idx += 3;
             }
             packet = MIDIPacketNext(packet); 
         }
    }

    dispatch_async(dispatch_get_main_queue(), ^{
        for (NSArray *packet in packetData) {
            [object receiveMIDIInput:packet];
        }
    });
}

Upvotes: 1

Related Questions