Reputation: 1283
I'm trying to implement CoreMIDI in my iOS app and I'm having trouble trying to debug it right now. Currently I have a UILabel that updates whenever the my MIDI callback is called. However, my UILabel never updates! I am not sure why this is happening and I'm guessing it's either how I'm defining something in my MIDI initialization or how I'm calling the UILabel. I'm still trying to figure this out but is there a better way to debug MIDI on an iOS app (as iOS devices only have one port and can only use the port for either connecting to computer or a MIDI controller at a given time).
How I'm creating the MIDI client:
Check(MIDIClientCreate(CFSTR("Yun Client"), NULL, NULL , &client));
Check(MIDIOutputPortCreate(client, CFSTR("Yun Output Port"), &outputPort));
Check(MIDIInputPortCreate(client, CFSTR("Yun Input Port"), MIDIInputCallback,
(__bridge void *)self, &inputPort));
unsigned long sourceCount = MIDIGetNumberOfSources();
CFStringRef endpointName;
for (int i = 0; i < sourceCount; ++i) {
MIDIEndpointRef endPoint = MIDIGetSource(i);
endpointName = NULL;
Check(MIDIObjectGetStringProperty(endPoint, kMIDIPropertyName, &endpointName));
Check(MIDIPortConnectSource(inputPort, endPoint, NULL));
[param addToMIDIInputsArray:[NSString stringWithFormat:@"%@", endpointName]];
}
My MIDI callback:
// MIDI receiver callback
static void MIDIInputCallback(const MIDIPacketList *pktlist,
void *refCon, void *connRefCon) {
SynthViewController *vc = (__bridge SynthViewController*)refCon;
MIDIPacket *packet = (MIDIPacket *)pktlist->packet;
Byte midiCommand = packet->data[0] >> 4;
NSInteger command = midiCommand;
Byte noteByte = packet->data[1] & 0x7F;
NSInteger note = noteByte;
Byte velocityByte = packet->data[2] & 0x7F;
float velocity = [[NSNumber numberWithInt:velocityByte] floatValue];
// Note On event
if (command == 9 && velocity > 0) {
[vc midiKeyDown:(note+4) withVelocity:velocity];
}
// Note off event
else if ((command == 9 || command == 8) && velocity == 0) {
[vc midiKeyUp:(note+4)];
}
[vc.logLabel addLogLine:[NSString stringWithFormat:@"%lu - %lu - %lu",
(long)command, (long)note, (long)velocityByte]];
}
addLogLine
method:
- (void)addLogLine:(NSString *)line {
NSString *str = [NSString stringWithFormat:@"%d - %@", _cnt++, line];
_logLabel.text = str;
}
Any help is great! Thanks
Upvotes: 0
Views: 338
Reputation: 27984
The header documentation for MIDIInputPortCreate
says:
readProc will be called on a separate high-priority thread owned by CoreMIDI.
You must update UIKit on the main thread only.
Use dispatch_async
to transfer control to the main thread, after you've parsed the incoming MIDI data.
static void MIDIInputCallback(const MIDIPacketList *pktlist,
void *refCon, void *connRefCon) {
SynthViewController *vc = (__bridge SynthViewController*)refCon;
// ...
dispatch_async(dispatch_get_main_queue(), ^{
// Note On event
if (command == 9 && velocity > 0) {
[vc midiKeyDown:(note+4) withVelocity:velocity];
}
// Note off event
else if ((command == 9 || command == 8) && velocity == 0) {
[vc midiKeyUp:(note+4)];
}
[vc.logLabel addLogLine:[NSString stringWithFormat:@"%lu - %lu - %lu", (long)command, (long)note, (long)velocityByte]];
});
}
Upvotes: 2