0

我在我的 OSX 应用程序中有一个线程,我在其中处理存储在 packetList 中的 midi 消息,并使用 MIDIReceived(deviceEndpoint, packetList) 将它们发送到虚拟仪器;作为我程序的一部分,我一次发送 16 个音符关闭消息,告诉虚拟乐器停止演奏所有 16 个音符。

有一些奇怪的 - 如果我启用调试消息 NSLog(@"Num Packets %d", packetList->numPackets); 代码工作正常。但是,如果我使用 NSLog(@"Num Packets %d", packetList->numPackets); 离开时,有些音符有时不会关闭。就好像有些消息被跳过了,因为线程运行得太快了。

有人可以向我解释为什么会这样吗?非常感谢。

- (void) processMIDIThread:(NSObject*)param {

    @autoreleasepool {

MAIN:
        for (;;) {

            if([[NSThread currentThread] isCancelled]) {
                NSLog(@"Thread has been cancelled");
                goto END;
            }
            int pktToTrigger = 0;

            if (midiMode==kKeyboardMode)
                pktToTrigger = 1; // in case note off message is lost
            else
                pktToTrigger = 3;

            // Queue processing starts here
            if (packetList->numPackets >= pktToTrigger) {
                NSLog(@"Num Packets %d", packetList->numPackets);
                OSStatus res = MIDIReceived(deviceEndpoint, packetList);
                if (res)
                    NSLog(@"Problem sending midi packets to virtual device");
//                NSLog(@"Sent %d %d %d" ,(int)packetList->packet->data[0],(int)packetList->packet->data[1],(int)packetList->packet->data[2]);
                [self clearPacketList];
            }
        }
    }
END: [NSThread exit];
     NSLog(@"Exited current thread.");
    ;
}

添加数据包功能

- (void) addPacketToPacketList:(Byte*) data ofLength:(int) len {

    if (_midiDeviceMode==kMidiOut) {
        //NSLog(@"length %d", len);
        //NSLog(@"%lld", mach_absolute_time());
        //NSLog(@"Insert %d %d %d" ,(int)data[0],(int)data[1],(int)data[2]);
        currentPacket = MIDIPacketListAdd(packetList, PACKETLIST_SIZE, currentPacket, mach_absolute_time(), len, data);

        //packetReady = YES;
        if (!currentPacket) exit(1);
    }


}

另一个类的调用函数

-(void) sendAllNoteOffs {

    NSMutableArray* noteZoneArray = [_keyboardView noteZoneArray];

    for (int i=0; i < noteZoneArray.count; i++) {
        NoteZone* nz = [noteZoneArray objectAtIndex:i];
        if ([nz lastNotePlayed]) {
            NotePacket* note = [NotePacket initWithLeapValue:127 forNote:[nz noteValue] noteOn:NO forChan:_keyboardChannel];
            [_virtualMIDIDevice addPacketToPacketList:note->data ofLength:note->length];
//            [_virtualMIDIDevice addPacketToPacketList:note->data ofLength:note->length];
            [nz setLastNotePlayed:NO];
        }
        [nz setHighlightedOn:NO];
    }
    [_virtualMIDIDevice setAllNotesOffSent:YES];
}

更新: 用以下内容替换调试语句似乎也可以。

[NSThread sleepForTimeInterval:0.0000001];

但我仍然没有很好的解释。虽然不明显,但这意味着音符之间存在延迟。

4

0 回答 0