MIDI 报文中插入 F8 就错位,怎样保留 Running Status 解析状态
MIDI实时消息F8可以插在其他消息的数据字节之间,并且不清除Running Status。解析器若把任何高位为一的字节都当作新普通消息开头,就会丢掉正在组装的音符。System Common消息则会清除运行状态,两种情况必须分开。
先固定输入与适用条件
本题使用MIDI 1.0串行字节流规则,不是USB-MIDI事件包或MIDI 2.0 UMP。夹具只实现Note On、Note Off、F8和F1需要的最小子集,未知消息会明确拒绝;不能把一个专项状态机称为完整MIDI解析库。实际输入若带端口包头,应先按对应传输格式解包。
本篇的OSC内容限定1.0规范,MIDI内容限定1.0字节消息;未涉及MIDI 2.0的UMP编码。桥接动作属于接收应用约定,不能从协议格式推断产品已经支持。
按字段与边界执行
-
为通道消息保存当前状态和已收数据。相同状态被省略时,后续数据继续依Running Status组成消息;首条消息没有状态时不得猜测。
-
遇到F8先输出独立实时事件,然后恢复原来的半条消息和运行状态。不要把F8当成音符力度,也不要清掉已经收到的note字节。
-
遇到F1等System Common时,清除通道运行状态,再按该消息所需长度读取数据。完成后出现无状态的数据字节,应标为孤立数据。
-
用含插入实时字节、显式状态切换与孤立数据的输入复跑。最终不仅检查事件数,还要检查每个事件的原始字节来源,防止错位后仍拼出貌似合理的note。
用具体样例核对结果
90 3C 64形成第一个Note On;接着3D F8 40中,3D和40组成沿用0x90的第二个Note On,F8是独立Clock。随后F1 00清除Running Status,尾部3E 20不能再解释为第三个Note On。附件结果明确列出两条音符、一条Clock、一条Quarter Frame和两个孤立字节。
通过条件是实时事件不破坏半条消息,System Common之后不继续套旧状态,孤立输入被报告。若只把每三个字节切为一组,夹具会立即暴露错误。真实网络MIDI或文件格式有各自封装与时间字段,不能跳过外层解析后直接用本脚本判断原始包的每个字节。
下载与复现
analyze.py、input.json、result.json。
下载的hex足够重现这个边界,脚本输出每类事件与孤立数据,不创建端口。交接时注明源传输类型及支持消息集合,扩展到SysEx等消息前需增加对应状态与边界验证。
把输入与脚本保存到同一个本地目录后执行 python analyze.py,脚本只读取输入、计算并重写同目录的结果文件。先保留原始附件副本,再将自己的脱敏输入另存为新版本,记录输入摘要与执行日期;不要把合成字段覆盖成看似真实的现场日志。
已用 Python 3.12.4 实际运行附件算法并检查断言。结果来自同目录合成输入;没有接入真实NDI源、控制器、灯具、接收卡或LED屏,不能据此填写现场验收通过。
对接下一步与一级来源
基础背景可看MIDI 控制协议在展厅的应用速查。相关流程收在展厅中控专题;需要项目对接时,带上本文输入及结果向SoftControl核对实际能力。
一级来源核对日期:2026-10-24。原始协议规则、本文原创运算和目标系统行为应分别留证;附件计算正确,不等于设备已经按该参数工作。
相关阅读
留言讨论
评论发布后会被人工复核,违规内容将被删除。
如果发表没有反应,可以前往联系我们告诉我们。