2016-02-25 110 views
0

我试图在我的iOS应用程序中实现CoreMIDI,并且现在尝试调试它时遇到问题。目前我有一个UILabel,只要我的MIDI回调被调用就会更新。但是,我的UILabel永远不会更新!我不知道为什么会发生这种情况,我猜测它是如何在MIDI初始化中定义某些内容或如何调用UILabel。我仍然试图弄清楚这一点,但是有没有更好的方法来在iOS应用程序上调试MIDI(因为iOS设备只有一个端口,并且只能在给定时间使用端口连接到计算机或MIDI控制器) 。在iOS应用程序中调试MIDI

我是如何创建的MIDI客户端:

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]]; 
} 

我MIDI回调:

// 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方法:

- (void)addLogLine:(NSString *)line { 
    NSString *str = [NSString stringWithFormat:@"%d - %@", _cnt++, line]; 
    _logLabel.text = str; 
} 

任何帮助是巨大的!由于

回答

2

标题文档MIDIInputPortCreate说:

readProc将通过 CoreMIDI拥有一个独立的高优先级的线程调用。

您必须只在主线程上更新UIKit。

使用dispatch_async将控制权转移到主线程后,解析传入的MIDI数据。

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]]; 
    }); 
} 
+0

啊!谢谢,我应该更仔细地阅读文档。非常感谢这做到了 –