loopback MIDIReadProc выходного MIDIPortRef (отправлять сообщения coremidi на входной порт) - PullRequest
0 голосов
/ 24 августа 2018

Я пишу приложение, которое воспроизводит полифонические ноты 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 не вызывается, когда игрок посылает миди-аут.

любая помощь приветствуется.

...