我在我的 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];
但我仍然没有很好的解释。虽然不明显,但这意味着音符之间存在延迟。