MIDIPacketList,numPackets始终为1

Dom*_*Cat 5 midi cocoa sysex ipad coremidi

我正在iPad上处理Midi,一切正常,我可以记录进来的所有东西,并且一切正常。但是,在尝试接收长消息(即Sysex)时,我只能得到一个最大为256字节的数据包,此后什么也没有。

使用Apple提供的代码:

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

packetList->numPackets始终为1。收到第一条消息后,在发送“新” sysex消息之前,不会调用其他回调方法。我不认为我的MIDI处理方法可以用全packetList(可能是任意大小)来调用。我以为我会以流的形式接收数据。它是否正确?

深入研究后,我发现的唯一内容是:http : //lists.apple.com/archives/coreaudio-api/2010/May/msg00189.html,其中提到了完全相同的内容,但并没有太大帮助。我知道我可能需要实现缓冲,但是我什至看不到任何超出前256个字节的内容,因此我不确定从哪里开始。

Nik*_*man 4

我的直觉是,系统要么将整个 sysex 消息塞进一个数据包,要么将其分解为多个数据包。根据CoreMidi文档,dataMIDIPacket 结构的字段有一些有趣的属性:

可变长度的 MIDI 消息流。不允许运行状态。在系统专有消息的情况下,数据包可能仅包含一条消息或消息的一部分,没有其他 MIDI 事件。

数据包中的 MIDI 消息必须始终完整,系统独有的除外。

(其长度被声明为 256 字节,因此客户端不必在简单情况下创建自定义数据结构。)

所以基本上,您应该查看 的声明length字段MIDIPacket,看看它是否大于 256。根据规范,256 字节只是标准分配,但如果需要,该数组可以容纳更多字节。您可能会发现整个消息已被塞入该数组中。

否则,系统似乎将 sysex 消息分解为多个数据包。由于规范规定不允许运行状态,因此它必须发送多个数据包,每个数据包都有一个前导0xF0字节。然后,您需要创建自己的内部缓冲区来存储这些消息的内容,根据需要剥离状态字节或标头,并将数据附加到缓冲区,直到读取表示0xF7序列结束的字节。

  • 经过更多测试后,我发现为 Mac OS X(而不是 iOS)编译的完全相同的代码可以按照我想要的方式工作,因此这似乎是 iOS 的错误/限制。仅供参考,消息的每个部分都被分成单独的 MIDIPacketList,每个 MIDIPacket 有 1 个 256 字节的 MIDIPacket。由于某种原因,iOS 似乎只看到第一个 MIDIPacketList。 (2认同)