2010-12-28 10 views
4

Ich bin Midi auf dem iPad verarbeiten und alles funktioniert gut und ich kann alles protokollieren, was kommt und alles funktioniert wie erwartet. Wenn ich jedoch versuche, lange Nachrichten (dh Sysex) zu empfangen, kann ich nur ein Paket mit maximal 256 Bytes und nichts danach erhalten.MIDIPacketList, numPackets ist immer 1

den Code Verwenden von Apple zur Verfügung gestellt:

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

packetList->numPackets ist immer 1. Nachdem ich die erste Nachricht erhalten, werden keine weiteren Rückrufmethoden aufgerufen, bis eine ‚neue‘ sysex Nachricht gesendet wird. Ich denke nicht, dass meine MIDI-Verarbeitungsmethode mit der vollständigen packetList (die möglicherweise eine beliebige Größe haben könnte) aufgerufen würde. Ich hätte gedacht, ich würde die Daten als Stream erhalten. Ist das richtig?

Nach dem Graben um das einzige, was ich finden konnte war das: http://lists.apple.com/archives/coreaudio-api/2010/May/msg00189.html, die genau das gleiche erwähnt, aber war nicht viel Hilfe. Ich verstehe, dass ich wahrscheinlich Pufferung implementieren muss, aber ich kann nicht einmal etwas hinter den ersten 256 Bytes sehen, also bin ich nicht sicher, wo ich überhaupt anfangen soll.

+0

Beachten Sie, dass Apples Code einen kleinen Fehler enthält - das '>' im bedingten Teil der 'for' Schleife sollte sein ein '<'. Es wird nicht helfen, Ihr Problem leider zu beheben. –

+0

HINWEIS: Die Handlung verdichtet sich. Bei iOS mit einem externen Gerät wie dem Line 6 MIDI Mobilizer II (oder dem iRig oder iConnect) wird der Sysex nicht einfach in mehrere Pakete aufgeteilt. Es ist in mehrere Paketlisten aufgeteilt, von denen jede ein einzelnes Paket mit einer Länge von 3 enthält. Dies ist meine persönliche Hölle, die ich gerade entdeckt habe. –

Antwort

2

Mein Bauchgefühl ist hier, dass das System entweder die gesamte Sysex-Nachricht in ein Paket stopft oder es in mehrere Pakete zerlegt. Nach Angaben der CoreMidi Dokumentation hat der data Feld der MIDIPacket Struktur einige interessante Eigenschaften:

Ein variabler Länge Strom von MIDI-Meldungen. Der Laufstatus ist nicht erlaubt. Im Falle von systemexklusiven Nachrichten kann ein Paket nur eine einzelne Nachricht oder einen Teil von eins enthalten, ohne dass andere MIDI-Ereignisse vorliegen.

Die MIDI-Nachrichten im Paket müssen immer vollständig sein, außer für systemexklusive.

(Dies erklärt wird 256 Byte lang sein, damit Kunden müssen keine benutzerdefinierten Datenstrukturen in einfachen Situationen erstellen.)

Also im Grunde, sollten Sie bei dem angegebenen length Feld der MIDIPacket aussehen und sehen, ob es größer als 256 ist. Laut Spezifikation sind 256 Bytes nur die Standardzuweisung, aber dieses Array kann bei Bedarf mehr enthalten. Möglicherweise stellen Sie fest, dass die gesamte Nachricht in dieses Array gepackt wurde.

Andernfalls scheint das System die Sysex-Nachrichten in mehrere Pakete zu brechen. Da die Spezifikation besagt, dass der Laufstatus nicht erlaubt ist, müsste sie mehrere Pakete mit jeweils einem führenden 0xF0 Byte senden. Sie müssten dann Ihren eigenen internen Puffer erstellen, um den Inhalt dieser Nachrichten zu speichern, indem Sie die Statusbytes oder den Header nach Bedarf entfernen und die Daten an Ihren Puffer anhängen, bis Sie ein Byte 0xF7 lesen, das das Ende der Sequenz angibt.

+0

Danke Nick, hat mir aber nicht geholfen. Wenn man sich die Länge des MIDIPackets ansieht, ist es bei kleineren Nachrichten so, wie man es erwarten würde, aber bei längeren Nachrichten erreicht es 256 und nicht darüber hinaus, egal wie groß die Sysex-Nachricht ist, die ich ihm sende. Ich dachte, es muss es in Pakete aufteilen, aber die MIDIPacketLists bekomme ich immer nur ein Paket. Nachdem das erste 256 Paket gesendet wurde, bekomme ich gar nichts. –

+2

Nach einigen weiteren Tests habe ich festgestellt, dass der exakt gleiche Code, der für Mac OS X (und nicht für iOS) kompiliert wurde, so funktioniert, wie ich es möchte, also scheint es sich um einen Fehler/Einschränkung bei iOS zu handeln. FYI, jeder Teil der Nachrichten wurde in separate MIDIPacketLists mit jeweils 1 MIDIPacket von 256 Bytes aufgeteilt. Aus irgendeinem Grund scheint iOS immer nur die erste MIDIPacketList zu sehen. –

+0

@ Domestic Cat, wissen Sie zufällig, ob das immer noch dasselbe ist? –

1

Ich hatte ein ähnliches Problem auf iOS. Du hast Recht MIDI-Pakete Nummer ist immer 1.

In meinem Fall, wenn mehrere MIDI-Events mit dem gleichen Timestamp (MIDI-Events zur gleichen Zeit) empfangen, teilt iOS diese mehrere MIDI-Events in mehreren Paketen nicht, als erwartet.

Aber zum Glück ist nichts verloren! Anstatt mehrere Pakete mit der richtigen Anzahl an Bytes zu empfangen, erhalten Sie ein einzelnes Paket mit mehreren Ereignissen und die Anzahl der Bytes wird entsprechend erhöht.

Also hier, was Sie tun müssen, ist:

In Ihrem MIDI IN Rückruf, analysieren alle Pakete (immer 1 für iOS) empfangen wird, dann für jedes Paket empfangen Sie die Länge des Pakets überprüfen müssen, sowie den MIDI-Status, dann führen Sie eine Schleife in diesem Paket durch, um alle MIDI-Ereignisse im aktuellen Paket abzurufen.

Wenn das Paket zum Beispiel 9 Bytes enthält und der MIDI-Status eine Note ON (3 Bytes Nachricht) ist, bedeutet dies, dass Ihr aktuelles Paket mehr als eine einzige Note enthält. Dann müssen Sie die erste Note analysieren (Bytes 0 bis 2), dann überprüfen Sie die folgenden MIDI-Status von Byte 3 und so weiter ..

Hope this helps ...

Jerome

Verwandte Themen