2016-02-25 5 views
0

Я пытаюсь реализовать CoreMIDI в своем приложении iOS, и у меня возникли проблемы с его отладкой прямо сейчас. В настоящее время у меня есть UILabel, который обновляется всякий раз, когда вызывается мой обратный вызов MIDI. Однако мой UILabel никогда не обновляется! Я не уверен, почему это происходит, и я предполагаю, что это то, как я определяю что-то в своей инициализации MIDI или как я называю UILabel. Я все еще пытаюсь понять это, но есть лучший способ отладки MIDI в приложении iOS (поскольку устройства iOS имеют только один порт и могут использовать только порт для подключения к компьютеру или MIDI-контроллеру в данный момент времени) ,Отладка MIDI в приложении iOS

Как я создаю клиент 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

Ах! Спасибо, я должен был внимательно прочитать документацию. Спасибо, что это сделал –