2016-02-25 213 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

啊!謝謝,我應該更仔細地閱讀文檔。非常感謝這做到了 –