Я пишу приложение, которое воспроизводит полифонические ноты Midi.Каждую ноту можно обрабатывать асинхронно, чтобы в последовательности временных шагов мой объект проигрывателя циклически повторял ноты данного шага, чтобы обработать их и воспроизвести, когда процесс завершится.Я не знаю заранее, завершится ли процесс на следующем шаге по времени, поэтому, когда наступит подходящее время, игрок отправит заметки по отдельности в coreMidi.
(это функция coreMidi)
MIDISend(outputPort, outputEndpoint, packetList)
Теперь волшебство начинается, и даже если я отправляю packageLists из одной заметки (содержащей один пакет MIDIPackage длиной три байта каждый раз), coreMidi «мудро» собирает заметки вместе в соответствии со своей отметкой времени, так что получатель читает MIDIPackagesиз нескольких нот (для полифонических событий).
Все работает хорошо с midi-in и midi-out per se, и мое приложение правильно отправляет и получает правильное количество нот.
Теперь проблема: мне нужно, чтобы конечная точка вывода знала, что фактически отправляется каждый раз из выходного порта.Как обратная связь между миди-аутом и миди-ином.Мне кажется логичным создать обратный вызов так же, как и я, чтобы читать с порта ввода 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
MIDIReadNoteProc2 не вызывается, когда игрок посылает миди-аут.
любая помощь приветствуется.