MIDI 控制协议在展厅的应用速查
依据 MIDI Manufacturers Association(MMA)公开的 MIDI 1.0 规范整理,具体型号支持以厂商手册为准。
从一次”声光对不齐”说起
沉浸式展项调试,画面里鼓点砸下去的那一帧,头顶那排灯要跟着爆闪。播放器归播放器、灯光台归灯光台,各跑各的时钟,结果开馆试了几遍,灯总比画面慢半拍——有时慢 200 毫秒,有时又莫名对上了,飘忽不定。你可能会去怪灯具反应慢,或者怀疑播放器卡顿,其实两样都没坏。病根是两台设备之间没有一条共同的”节拍线”,各自按各自的时基跑,误差自然越攒越大。这种”声光机”要严丝合缝咬在一起的场合,恰恰是 MIDI 最擅长的活。它不传声音、不传画面,只传一个个又轻又快的”触发点”,让多台设备踩在同一个鼓点上。这篇把 MIDI 的字节结构、通道消息到展厅里怎么拿它做联动讲透,让你下次遇到声光错位能顺着协议一层层往下查。
MIDI 是什么
MIDI(Musical Instrument Digital Interface,乐器数字接口)是一种用于乐器、合成器与多媒体设备之间传递演奏与控制信息的数字协议,由 MMA(MIDI Manufacturers Association)于 1983 年制定,几十年间几乎没做破坏性改动,老设备和新设备至今能对话。关键要抓住一点:它传的不是音频波形,而是”发生了什么事”的指令——按了哪个键、力度多大、松开了没、换成哪个音色。一个 Note On 消息只有三个字节,描述”某通道某个音以某个力度被按下”,接收端自己去把这个音合成出来。正因为传的是事件而非声音,MIDI 数据量极小、实时性好,天生适合做多设备之间的触发与同步信号。在展厅里,它很少真的去弹一段旋律,更多是被当成一条”发令线”:一个音符触发一段视频、一次力度值调一路灯光亮度、一条 Program Change 让全场切换到下一个场景。
核心硬货:字节怎么排
MIDI 消息由**状态字节(Status Byte)和数据字节(Data Byte)**拼成,两者靠最高位(bit7)区分,这是读懂 MIDI 抓包的第一把钥匙:
- 状态字节:最高位为 1,取值
0x80–0xFF。高 4 位是消息类型,低 4 位是通道号(0–15,对应人说的 1–16 通道)。 - 数据字节:最高位为 0,取值
0x00–0x7F(即 0–127)。所以 MIDI 里一切参数(音符、力度、控制器值)都只有 128 级。
以最常见的 Note On 为例,三字节结构是:
状态字节 0x9n → Note On,n = 通道号(0x90=通道1,0x91=通道2 ...)
数据字节1 0nnnnnnn → 音符号 0–127(60 = 中央 C)
数据字节2 0vvvvvvv → 力度 0–127(0 力度 = 等价于松开)
把主要通道消息列成表,对着设备手册就能逐字节读懂它在发什么:
| 消息类型 | 状态字节 | 数据字节1 | 数据字节2 | 展厅里干嘛用 |
|---|---|---|---|---|
| Note On | 0x90–0x9F | 音符号 | 力度 | 触发某段节目/动作 |
| Note Off | 0x80–0x8F | 音符号 | 释放力度 | 结束触发/复位 |
| Control Change (CC) | 0xB0–0xBF | 控制器号 | 值 0–127 | 调亮度/音量/切场景开关 |
| Program Change | 0xC0–0xCF | 编号 0–127 | —(仅 1 数据字节) | 整场切换预设场景 |
| Pitch Bend | 0xE0–0xEF | 低 7 位 | 高 7 位 | 连续量微调(少用) |
几个必须记住的机制:
- 通道 16 路:状态字节低 4 位寻址,同一根线上能跑 16 个互不干扰的逻辑通道,让不同设备各认各的频道。
- 运行状态(Running Status):连续发同类型消息时,后续可省略重复的状态字节,只发数据字节,省带宽也降延迟。抓包时看到”一串裸数据字节没有状态头”,多半就是它在起作用,别当成丢包。
- 系统实时消息:像 Timing Clock(
0xF8)、Start(0xFA)、Stop(0xFC)这类单字节消息,可以插在任何消息中间发,用来做全场时钟同步,是”帧级对齐”的底层依靠。 - 系统专用消息(SysEx):
0xF0开头、0xF7结尾,中间长度可变,留给厂商塞私有数据(如设备型号问答、参数批量下发)。
关键参数
| 项目 | 值 |
|---|---|
| 传输方式 | 异步串行,5 mA 电流环,光耦隔离 |
| 速率(波特率) | 31250 bit/s(±1%,固定不可调) |
| 帧格式 | 8N1(1 起始 + 8 数据 + 1 停止,无校验) |
| 每字节耗时 | 320 µs(10 位 ÷ 31250) |
| 三字节消息耗时 | 约 960 µs(近 1 ms) |
| 物理接口 | 传统 5 针 DIN;现代设备也走 USB-MIDI / RTP-MIDI |
| 通道数 | 16 个(状态字节低 4 位寻址) |
| 数据取值 | 数据字节 0–127(7 位) |
| 传输方向 | 单向(IN/OUT/THRU 各自独立),无握手应答 |
| 标准组织 | MMA(MIDI Manufacturers Association) |
工作原理:一条单向的发令线
MIDI 物理层是 5 mA 电流环加光耦隔离,这个设计有讲究:光耦把收发两端电气隔开,一台设备的地线噪声、甚至意外的强电,不会顺着信号线窜到另一台,多设备互联时保命。但它是纯单向的——OUT 口只发不收,IN 口只收不发,没有任何应答握手。这意味着 MIDI 从不知道对方收没收到,发出去就当成功了。展厅里由此带来一个现实:MIDI 触发不可靠时不会报错,只会”没反应”,排查时不能指望它自己吐错误码。
多台设备串联靠 THRU 口:THRU 把 IN 收到的数据原样转发出去,于是能 A→B→C 一路串下去,所有设备收到同一份消息。但 THRU 每级都有微小延迟和信号衰减,串太多级(一般超过 3–4 级)末端会开始丢消息或时序抖动,大场子改用 MIDI 分配器(一进多出)并联下发,而不是一味串 THRU。31250 波特下一个三字节消息占近 1 毫秒,同一时刻要触发几十个音符时,它们其实是排队串行发出的,会有先后微差——这就是为什么密集触发场景要用系统实时时钟做基准,而不是靠消息本身的到达顺序去对齐。
展厅实战对接
MIDI 在展厅极少单打独斗,几乎总是挂在中控系统下面当”触发层”,典型链路是:中控主机(或时间表引擎)→ MIDI OUT → 各台设备(播放器 / 灯光台 / 机械控制器)。落地时几种常见打法:
- 节目触发:中控在某个时间点或按钮上绑定一条 Note On / Program Change,一发出去,视频、音频、灯光场景多设备同时响应,做到”一键起全场”。
- 声光同步:把灯光台和播放器都接进同一条 MIDI 时钟,靠 Timing Clock 系统实时消息做统一节拍,灯效才能咬着画面鼓点走,解决开头那个”慢半拍”的老问题。
- 场景切换:用 Control Change 或 Program Change 一次性把全场从”开馆”切到”讲解”再到”闭馆”,由中控统一编排下发,讲解员一个动作全场景联动。
- 机械与特效联动:触发升降台、雾机、互动装置的动作,让机械节奏踩上画面节拍。
真正干活时,MIDI 的底层字节差异会被中控软件屏蔽掉,运营只面对”场景”这一层。用 SoftControl 展厅中控 把 MIDI 触发和灯光、播控编排到同一条时间线上,配合 SoftPlayer 展厅播控 做多媒体联动,“声光机”就能拧成一股绳。这套”预存场景 + 触发下发”的思路,和 DMX512 灯光协议 里把通道值预存成灯光场景、Modbus 协议 里把设备动作封装成开关,是同一套中控哲学——底层协议各不相同,对外只暴露”触发一个场景”。
对比选型:MIDI、DMX512、串口指令怎么分工
展厅里这几种控制信号常常同台,别用错地方:
| 维度 | MIDI | DMX512 | 串口指令(RS232/422/485) |
|---|---|---|---|
| 定位 | 事件触发 / 时钟同步 | 灯具逐通道连续控制 | 设备一对一发码控制 |
| 数据性质 | 离散事件(按下/切换) | 每通道 0–255 连续值 | 厂商自定文本/字节指令 |
| 实时性 | 极高(消息只几字节) | 满帧约 44 Hz 刷新 | 看波特率与指令长度 |
| 典型对象 | 播放器、时钟、机械触发 | 洗墙灯、摇头灯、像素灯带 | 投影机、矩阵、电视 |
| 反馈能力 | 无(单向) | 无(RDM 才双向) | 多数可查询回读状态 |
一句话分工:要”何时发生”用 MIDI,要”灯亮多少”用 DMX512,要”让某台设备执行某条命令”用串口指令。 真实场子往往三者叠用,中控在上层把它们编织成一条时间线。
故障排查表
| 现象 | 可能原因 | 排查 / 解决 |
|---|---|---|
| 发触发完全没反应 | OUT/IN 接反,或线接错口 | MIDI 是单向,OUT 必须接对方 IN,别 OUT 对 OUT |
| 声光稳定慢半拍 | 两设备各跑各时钟,无统一时基 | 引入 MIDI Timing Clock 做全场同步基准 |
| 触发时有时无、飘忽 | THRU 串太多级,末端丢消息 | 减少 THRU 层数,改用 MIDI 分配器并联下发 |
| 通道对不上、发 A 设备 B 响应 | 收发通道号(1–16)设置不一致 | 核对状态字节低 4 位,两端通道号对齐 |
| 密集触发时个别丢失 | 同刻消息串行排队、带宽挤占 | 错开触发时刻,或拆到不同物理链路 |
| 收到一串裸数据没状态头 | Running Status 省略了状态字节 | 正常机制,按上一条同类型消息解析,非丢包 |
| SysEx 参数下发失败 | 厂商 ID / 帧尾 0xF7 不匹配 | 对照手册核 0xF0…0xF7 完整帧结构 |
排查口诀:先确认接线方向(单向别接反),再看通道号对没对齐,最后才查时钟同步。 MIDI 不会自己报错,只会沉默,所以每一步都得靠抓包和手册硬核对。
进阶与边界
USB-MIDI 与网络 MIDI:传统 5 针 DIN 之外,现代设备普遍支持 USB-MIDI(直接插电脑)和 RTP-MIDI(走以太网跨机房传 MIDI),大展厅用后者能让中控主机跨楼层给远端设备发触发,省去长距离串口布线。协议语义不变,变的只是承载方式。
MIDI 2.0:MMA 后续推出的新版本引入双向协商、更高分辨率(不再只有 128 级)和逐音符控制,但落地设备仍在铺开,绝大多数展厅现役仍是 MIDI 1.0。做方案时以在场设备的实际支持为准,别默认对方能吃 2.0 消息。
能力边界:MIDI 只管”触发和同步”,它不传画面、不传声音、也回读不了设备状态。要查设备开没开、投影机灯泡还剩多少小时,得靠串口查询指令或网络协议,别指望 MIDI 给你答案。
动手检查清单
接一条 MIDI 触发链路前后,对着过一遍:
- OUT→IN 方向接对,没有 OUT 对 OUT / IN 对 IN
- 收发两端通道号(1–16)一致,各设备频道不打架
- 需要声光同步的,已引入统一 Timing Clock 基准
- THRU 串联不超过 3–4 级,超了改用分配器并联
- 触发消息类型选对(一次动作用 Note On,切场景用 Program Change)
- SysEx 帧头 0xF0 / 帧尾 0xF7 完整,厂商 ID 对得上
- 触发已在中控预存为场景并实测,时间表绑定无误
小结
MIDI 的内核很朴素:31250 固定波特、8N1 帧、状态字节最高位为 1 带通道号、数据字节 0–127、纯单向无应答。它在展厅里的价值从不是弹奏,而是当那条又快又轻的”发令线”——用一个音符、一条切换消息,让播放器、灯光、机械踩在同一个节拍上。真正决定现场顺不顺的,是那几条纪律:方向别接反、通道对齐、用系统时钟做同步基准。上层再由中控把这些触发封装成”场景”,声光机才真正拧成展厅叙事的一条线。
延伸阅读:了解 DMX512 灯光控制协议 如何逐通道驱动灯具、Modbus 设备控制协议 怎么控开关设备、TCP/UDP 通信基础,或查看全部设备协议速查。
需要把 MIDI 触发与灯光、播放节目编排到一起?了解 SoftControl 展厅中控、查看解决方案与落地案例,或直接联系我们聊聊你的定制需求。