我正在尝试为已停产的硬件鼓合成器实现一个编辑器,它使用未记录的系统专用 MIDI 消息进行通信。我已经弄清楚了补丁格式,但是我在使用校验和算法时遇到了麻烦。我尝试了各种方法和工具(例如复仇)来尝试计算并达到我的能力极限。
由于 MIDI 被限制为消息中的 7 位(页眉和页脚字节 F0/F7 除外),这一切都变得复杂了。所以还有一个额外的问题是如何处理溢出。
我试图理解两种类型的消息:
语音请求:
F0 33 7F 7F 08 03 07 40 00 0E F7
或者
F0 33 7F 7F 08 03 05 00 13 F7
其中倒数第二个字节(示例中为 0E,13)是某种校验和。我假设这两条消息使用相同的算法,但我什至不确定校验和计算实际上考虑了哪些字节(因为 0xF0 0x33 0x7F 总是存在于该仪器发送或接收的每条消息,它可能会被排除在外,但我不能确定)。这里还有一些示例:
F0 33 7F 7F 08 03 07 40 1A 57 F7
F0 33 7F 7F 08 03 07 40 1B 5F F7
F0 33 7F 7F 08 03 07 40 1C 67 F7
F0 33 7F 7F 08 03 07 40 1D 6F F7
F0 33 7F 7F 08 03 07 40 1E 77 F7
F0 33 7F 7F 08 03 07 40 1F 7F F7
F0 33 7F 7F 08 03 07 40 20 1C F7
F0 33 7F 7F 08 03 07 40 21 14 F7
F0 33 7F 7F 08 03 07 40 22 0C F7
F0 33 7F 7F 08 03 07 40 23 04 F7
F0 33 7F 7F 08 03 07 40 24 3C F7
F0 33 7F 7F 08 03 07 40 25 34 F7
F0 33 7F 7F 08 03 07 40 26 2C F7
F0 33 7F 7F 08 03 07 40 27 24 F7
F0 33 7F 7F 08 03 07 40 28 5C F7
F0 33 7F 7F 08 03 07 40 29 54 F7
或按校验和分组:
F0 33 7F 7F 08 03 07 44 0D 00 F7
F0 33 7F 7F 08 03 07 45 1F 00 F7
F0 33 7F 7F 08 03 07 47 2A 00 F7
F0 33 7F 7F 08 03 07 44 1C 01 F7
F0 33 7F 7F 08 03 07 45 0E 01 F7
F0 33 7F 7F 08 03 07 46 29 01 F7
F0 33 7F 7F 08 03 07 44 2F 02 F7
F0 33 7F 7F 08 03 07 46 1A 02 F7
F0 33 7F 7F 08 03 07 47 08 02 F7
F0 33 7F 7F 08 03 07 45 2C 03 F7
F0 33 7F 7F 08 03 07 46 0B 03 F7
F0 33 7F 7F 08 03 07 47 19 03 F7
F0 33 7F 7F 08 03 07 40 23 04 F7
F0 33 7F 7F 08 03 07 41 31 04 F7
F0 33 7F 7F 08 03 07 42 16 04 F7
F0 33 7F 7F 08 03 07 43 04 04 F7
F0 33 7F 7F 08 03 07 41 20 05 F7
F0 33 7F 7F 08 03 07 42 07 05 F7
F0 33 7F 7F 08 03 07 43 15 05 F7
F0 33 7F 7F 08 03 07 40 01 06 F7
F0 33 7F 7F 08 03 07 41 13 06 F7
F0 33 7F 7F 08 03 07 43 26 06 F7
F0 33 7F 7F 08 03 07 40 10 07 F7
F0 33 7F 7F 08 03 07 41 02 07 F7
F0 33 7F 7F 08 03 07 42 25 07 F7
F0 33 7F 7F 08 03 07 44 0F 10 F7
F0 33 7F 7F 08 03 07 45 1D 10 F7
F0 33 7F 7F 08 03 07 47 28 10 F7
校验和涵盖从 00 到 7F 的完整 7 位范围,但低 4 位的出现似乎与 0x4n 字节的低 4 位有关。
另一种类型的消息是实际的语音数据。此数据在数据包末尾使用 28 位(4 字节)校验和(总共 212 字节):
F0337F19 08030600 00040000 00000000 03600000 02540070 18001640 17100D19 16010808 60021219 4B103112 4A000000 06600000 003C0070 18001640 17100D19 32652008 34033D48 03102C4F 0A000000 16420000 00580110 18001640 16580D19 1E012C08 7401760A 13102F17 47000000 16420000 00500070 18001640 16580D19 32007408 68033D75 7B102F57 4C000000 06420000 00500070 18001640 16580D19 32007408 7002517A 13102F17 4A000000 16420000 00580070 18001640 16580D19 32005C09 10023202 13102F57 48000001 5D7C65F7
或者
F0337F19 08030600 00040000 00000000 03610000 02540070 18001640 17100D19 16010808 60021219 4B103112 4A000000 06600000 003C0070 18001640 17100D19 32652008 34033D48 03102C4F 0A000000 16420000 00580110 18001640 16580D19 1E012C08 7401760A 13102F17 47000000 16420000 00500070 18001640 16580D19 32007408 68033D75 7B102F57 4C000000 06420000 00500070 18001640 16580D19 32007408 7002517A 13102F17 4A000000 16420000 00580070 18001640 16580D19 32005C09 10023202 13102F57 48000000 6A7101F7
或者
F0337F19 08030600 00040000 00000000 03620000 02540070 18001640 17100D19 16010808 60021219 4B103112 4A000000 06600000 003C0070 18001640 17100D19 32652008 34033D48 03102C4F 0A000000 16420000 00580110 18001640 16580D19 1E012C08 7401760A 13102F17 47000000 16420000 00500070 18001640 16580D19 32007408 68033D75 7B102F57 4C000000 06420000 00500070 18001640 16580D19 32007408 7002517A 13102F17 4A000000 16420000 00580070 18001640 16580D19 32005C09 10023202 13102F57 48000003 73762BF7
对校验和的第 1 个字节 (01, 00, 03) 的更改以响应对字节 41 (0, 1, 2) 的低 4 位的更改当然是一个提示,但我不明白。
无论如何,如果有人对合理的进行方式有建议,我将不胜感激。制造该仪器的公司无意支持其旧(更)硬件,并且拒绝提供任何类型的系统专有文档。该公司出于类似目的在其他仪器上使用了 CRC 算法,但没有什么与我在这里看到的相符。
如果有任何兴趣,我很乐意提供额外的样本数据(我意识到只有几个样本是不够的)——我有 256 条请求消息和 160 多个完整的语音可供分析。我还可以生成数据来测试对完整消息的不同部分进行更改的效果。谢谢参观。
更新 1:
我已经解决了短消息的校验和。它是 的 CRC16(CCITT) (full message previous to that byte) >> 9 & 0x7F。我通过在反汇编程序中破解公司(请求语音库)的基于计算机的实用程序的二进制文件来解决这个问题。我猜长消息是类似的,只是有更多的字节,当我知道更多时会报告。
更新 2:
长消息的倒数第二个字节也使用上述公式。然而,之前的 3 个字节在这一点上仍然是个谜,我在我拥有的二进制文件中没有发现任何明显的东西——这些字节是在硬件上生成的,而不是在“客户端”上生成的。它看起来仍然像一个 16 位值,分布在 3 个 7 位限制字节上。我只是还没有确定这个价值是如何产生的。