6

私は iPad で Midi を処理していますが、すべて正常に動作しており、入ってくるものすべてをログに記録でき、すべて期待どおりに動作します。しかし、長いメッセージ (つまり Sysex) を受信しようとすると、最大 256 バイトのパケットを 1 つしか取得できず、その後は何も取得できません。

Apple が提供するコードを使用する:

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

packetList->numPacketsは常に 1 です。最初のメッセージを取得した後は、「新しい」sysex メッセージが送信されるまで、他のコールバック メソッドは呼び出されません。私の MIDI 処理メソッドが完全な packetList (潜在的に任意のサイズ) で呼び出されるとは思いません。データをストリームとして受け取ると思っていたでしょう。これは正しいです?

私が見つけた唯一のものはこれでした: http://lists.apple.com/archives/coreaudio-api/2010/May/msg00189.html、まったく同じことについて言及していますが、あまり役に立ちませんでした。おそらくバッファリングを実装する必要があることは理解していますが、最初の 256 バイト以降は何も表示されないため、どこから始めればよいかわかりません。

4

3 に答える 3

4

ここでの私の直感は、システムが sysex メッセージ全体を 1 つのパケットに詰め込むか、複数のパケットに分割するかのどちらかであるということです。CoreMidiのドキュメントによるとdata、MIDIPacket 構造体のフィールドにはいくつかの興味深いプロパティがあります。

MIDI メッセージの可変長ストリーム。実行中のステータスは許可されていません。システム エクスクルーシブ メッセージの場合、パケットには 1 つのメッセージまたはメッセージの一部のみが含まれ、他の MIDI イベントは含まれません。

パケット内の MIDI メッセージは、システム エクスクルーシブを除き、常に完全である必要があります。

(これは長さが 256 バイトであると宣言されているため、クライアントは単純な状況でカスタム データ構造を作成する必要はありません。)

したがって、基本的には、の宣言されたlengthフィールドをMIDIPacket見て、それが 256 より大きいかどうかを確認する必要があります。仕様によると、256 バイトは標準的な割り当てですが、必要に応じてその配列はそれ以上を保持できます。メッセージ全体がその配列に詰め込まれていることに気付くかもしれません。

それ以外の場合は、システムが sysex メッセージを複数のパケットに分割しているようです。仕様では、実行中のステータスは許可されていないため、複数のパケットを送信する必要があり、それぞれに先頭の0xF0バイトが含まれています。次に、これらのメッセージの内容を格納するための独自の内部バッファーを作成し、必要に応じてステータス バイトまたはヘッダーを取り除き0xF7、シーケンスの終わりを示すバイトを読み取るまでデータをバッファーに追加する必要があります。

于 2010-12-29T15:45:27.893 に答える
1

GitHub プロジェクトのこのファイルには、MIDI パケットをウォークスルーする方法の良いリファレンスがあります: https://github.com/krevis/MIDIApps/blob/master/Frameworks/SnoizeMIDI/SMMessageParser.m

(私のものではありませんが、このスレッドにたどり着いた問題を解決するのに役立ちました)

于 2014-02-26T14:06:22.073 に答える