我正在编写一个可播放和弦Midi音符的应用程序。可以异步处理每个音符,以便在一系列时间步骤中,我的播放器对象循环处理给定步骤的音符,以处理它们并在过程结束时播放。我不知道该过程是否会在将来的某个时间结束,因此,在合适的时间,播放器会将音符分别发送给coreMidi。
(这是coreMidi函数)
MIDISend(outputPort, outputEndpoint, packetList)
现在魔术开始了,即使我发送一个音符的packageList(每次包含一个三字节长的MIDIPackage),coreMidi也会根据它们的时间戳“明智地”将音符聚集在一起,以便接收器读取多个音符的MIDIPackages(用于复音事件。
一切与midi-in和midi-out本身都可以很好地工作,我的应用程序可以正确发送和接收正确数量的笔记。
现在是问题:我需要输出端点知道每次从输出端口实际发送的内容。就像中端输出和中端输入之间的反馈一样。 在我看来,创建与从Input Midi端口读取的回调相同的回调是合理的,但是我没有在API文档中找到任何内容,任何示例代码,而且我的所有实验都没有成功。
这是我尝试过的其他方法:
(创建连接)
MIDIClientRef client;
MIDIPortRef outputPort;
MIDIPortRef inputPort;
MIDIPortRef feedbackPort;
OSStatus s = MIDIClientCreate((CFStringRef)@"MidiMonitor MIDI Client", MIDINotifyMessageProc, (__bridge void *)(self), &client);
s = MIDIOutputPortCreate(client, (CFStringRef)@"MidiMonitor Output Port", &outputPort);
s = MIDIInputPortCreate(client, (CFStringRef)@"MidiMonitor Input Port", MIDIReadNoteProc, (__bridge void *)(self), &inputPort);
s = MIDIInputPortCreate(client, (CFStringRef)@"MidiMonitor Feedback", MIDIReadNoteProc2, (__bridge void *)(self), &feedbackPort);
const ItemCount numberOfSources = MIDIGetNumberOfSources();
for (int i = 0; i < numberOfSources; i++)
{
MIDIEndpointRef endpoint = MIDIGetSource(i);
CFStringRef endpointName = NULL;
MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &endpointName);
OSStatus s = MIDIPortConnectSource(inputPort, endpoint, (__bridge void *)(self));
s = MIDIPortConnectSource(feedbackPort, endpoint, (__bridge void *)(self));
}
(发送消息)
- (void) sendPacketList:(const MIDIPacketList *)packetList
{
for (ItemCount index = 0; index < MIDIGetNumberOfDestinations(); ++index)
{
MIDIEndpointRef outputEndpoint = MIDIGetDestination(index);
if (outputEndpoint)
{
OSStatus s = MIDISend(outputPort, outputEndpoint, packetList);
s = MIDISend(feedbackPort, outputEndpoint, packetList);
}
}
}
每次返回的OSStatus = 0
当播放器发送midi时,不会调用MIDIReadNoteProc2。
感谢您的帮助。