MIDIPacketList, numPackets всегда 1 - PullRequest
       30

MIDIPacketList, numPackets всегда 1

4 голосов
/ 28 декабря 2010

Я обрабатываю Midi на iPad, и все работает нормально, и я могу регистрировать все, что приходит, и все работает как положено.Однако, пытаясь получить длинные сообщения (например, Sysex), я могу получить только один пакет длиной не более 256 байт и ничего после этого.

Используя код, предоставленный Apple:

MIDIPacket *packet = &packetList->packet[0];
for (int i = 0; i > packetList->numPackets; ++i) {
    // ...
    packet = MIDIPacketNext (packet);
}

packetList->numPackets всегда равно 1. После того, как я получу это первое сообщение, никакие другие методы обратного вызова не вызываются, пока не будет отправлено «новое» синсекс-сообщение.Я не думаю, что мой метод обработки MIDI будет вызван с полным packageList (который потенциально может быть любого размера).Я бы подумал, что получу данные в виде потока.Правильно ли это?

После того, как покопаться, единственное, что я смог найти, это: http://lists.apple.com/archives/coreaudio-api/2010/May/msg00189.html,, в котором упоминается то же самое, но это не сильно помогло.Я понимаю, что мне, вероятно, нужно реализовать буферизацию, но я не вижу ничего, кроме первых 256 байтов, поэтому я не уверен, с чего начать.

Ответы [ 3 ]

2 голосов
/ 29 декабря 2010

Мое внутреннее ощущение здесь состоит в том, что система либо собирает все сообщение sysex в один пакет, либо разбивает его на несколько пакетов.Согласно документации CoreMidi , поле data структуры MIDIPacket обладает некоторыми интересными свойствами:

Поток MIDI-сообщений переменной длины.Статус работы не разрешен.В случае системных исключительных сообщений пакет может содержать только одно сообщение или его часть без каких-либо других событий MIDI.

MIDI-сообщения в пакете всегда должны быть завершены, за исключением системных исключений.

(объявляется, что его длина составляет 256 байт, поэтому клиентам не нужно создавать собственные структуры данных в простых ситуациях.)

Итак, в общем, вы должны посмотреть наlength поле MIDIPacket и посмотрите, больше ли оно 256. Согласно спецификации, 256 байтов - это просто стандартное распределение, но этот массив может содержать больше при необходимости.Возможно, вы обнаружите, что все сообщение было помещено в этот массив.

В противном случае кажется, что система разбивает сообщения sysex на несколько пакетов.Так как в спецификации сказано, что текущее состояние не разрешено, то ему придется отправлять несколько пакетов, каждый с начальным байтом 0xF0.Затем вам нужно будет создать собственный внутренний буфер для хранения содержимого этих сообщений, по мере необходимости убирая байты состояния или заголовок, и добавляя данные в ваш буфер, пока вы не прочитаете байт 0xF7, который обозначает конец последовательности..

1 голос
/ 17 января 2014

У меня была похожая проблема на iOS. Вы правы, количество MIDI-пакетов всегда равно 1.

В моем случае, при получении нескольких событий MIDI с одной и той же временной меткой (события MIDI, полученные в одно и то же время), iOS не разделяет эти несколько событий MIDI на несколько пакетов, как ожидалось.

Но, к счастью, ничего не потеряно! Действительно, вместо того, чтобы получать несколько пакетов с их правильным количеством байтов, вы получите один пакет с несколькими событиями в нем, и число байтов будет соответственно увеличено.

Итак, вот что вам нужно сделать:

В вашем обратном вызове MIDI IN проанализируйте все полученные пакеты (всегда 1 для iOS), затем для каждого полученного пакета вы должны проверить длину пакета, а также статус MIDI, а затем зациклиться на этом пакете, чтобы получить все события MIDI в текущем пакете.

Например, если пакет содержит 9 байтов, а статус MIDI - это нота ON (сообщение из 3 байтов), это означает, что ваш текущий пакет содержит более одной ON, тогда вы должны проанализировать первое ON (байты). От 0 до 2), затем проверьте следующий статус MIDI из байта 3 и т. Д.

Надеюсь, это поможет ...

Джером

0 голосов
/ 26 февраля 2014

В этом файле проекта GitHub есть хороший пример того, как пройти через MIDI-пакет: https://github.com/krevis/MIDIApps/blob/master/Frameworks/SnoizeMIDI/SMMessageParser.m

(Не мое, но оно помогло мне решить проблемы, которые привели меня к этой теме)

...