midi文件里都记录了哪些信息,是怎么编码的,怎么编码
MIDI 文件基础:记录什么 + 编码原理
MIDI不是音频!不存声音波形,只存「演奏指令」,这是最核心区别。
一、MIDI文件里面记录哪些信息
1. 核心事件(MIDI Event)
音符事件(Note On / Note Off)
Note On:按下琴键/鼓垫
- 参数:通道(0~15)、音号(0-127,代表音高)、力度(0-127)
- 注:力度=0的Note On等价于Note Off
Note Off:松开按键
- 参数:通道、音号、释放力度
控制器事件 CC(Control Change)
- 通道音量、声像、踩镲控制、弯音轮、表情、延音踏板等。
- 例如CC64=延音踏板,CC10=声像,CC7=通道音量
程序改变 Program Change
- 切换音色:比如通道1改成钢琴,通道10默认是打击乐通道(鼓组,这就是电鼓DTX用到的)
- 弯音 Pitch Wheel:滑音、音高偏移
- 通道触后、音符触后:键盘压力感应(手卷鼓一般不用)
2. 元事件(Meta Event,只存在MIDI文件,不发给硬件)
- 节拍、BPM(速度)、拍号(4/4)、调号
- 音轨名称、歌曲标题、版权、歌词文本
- 时间基准(TPQN,每四分音符多少tick):决定时间分辨率,常见480tick/四分音符
3. 时间信息:Tick + Delta-time(增量时间)
MIDI不是记录绝对时间,用Delta-Time(增量tick):
两个事件之间间隔多少tick,而不是“第2秒按下音符”
tick → 根据BPM换算成真实秒数。
4. 文件结构信息
- 音轨数量(Track):多轨MIDI可以鼓一轨、钢琴一轨分开。
- 格式:MIDI0(单轨) / MIDI1(多轨同步,最常用) / MIDI2(多轨异步很少用)
二、MIDI文件编码(标准:MIDI 1.0,.mid二进制文件)
MIDI文件由文件头块 + 多个音轨块组成,全部是大端(Big-Endian)二进制存储。
1. 文件头块(Header Chunk)
固定结构:
4字节块标识:MThd
4字节块长度:固定00 00 00 06
2字节:MIDI格式(0/1/2)
2字节:音轨数量
2字节:时间基准 TPQN示例十六进制:4D 54 68 64 00 00 00 06 00 01 00 02 01 E0
4D546864= ASCIIMThd- 后面6字节:格式=1,2条音轨,TPQN=480
2. 音轨块(Track Chunk,每条音轨一个MTrk)
4字节标识:MTrk
4字节:本音轨所有事件的总字节长度
然后:一连串【Delta-Time + MIDI事件】4D 54 72 6B = ASCII MTrk
重点:Delta-Time 编码 → 可变长度变长整数(VLQ,Variable Length Quantity)
这是MIDI最有特点的编码!
- 1~4字节,最高位bit7作为标记
- bit7=1:后面还有下一个字节;bit7=0:这是最后一个字节
- 每个字节只用低7bit存数值。
举例子:
数字 0x80 (128)
拆成7bit分段:01 0000000
编码:81 00
0x81:最高位=1,低7bit=1;0x00最高位0,低7bit=0
规则:从高位往低位,每7bit一组,除最后一组外,所有字节最高位置1。
MIDI事件编码(状态字节 + 数据字节)
状态字节高4bit=事件类型,低4bit=MIDI通道(0~15)
9x= Note On(x=通道),后面2字节:音号、力度8x= Note Off,后面2字节:音号、释放力度Ax= 音符触后Bx= CC控制器Cx= Program Change(只1个数据字节,音色号)Dx= 通道触后Ex= 弯音(2字节)
运行状态(Running Status)优化:连续同类型同通道事件,可以省略状态字节,只写数据,减少文件体积,MIDI文件常用。
Meta元事件(FF开头)
状态字节固定0xFF,后面1字节元事件类型,1字节VLQ长度,再是内容。
例:FF 51 03 07 A1 20 → 设置BPM(微秒/四分音符)
三、简化编码流程(写一个MIDI文件的步骤)
- 写Header块:MThd + 长度 + 格式、轨道数、TPQN
对每一条音轨:
- 写入MTrk标识 + 预留长度(写完事件后回填)
- 遍历所有演奏事件,按时间先后排序
- 计算两个事件之间tick差值,用VLQ编码Delta-Time
- 写入事件状态+数据(使用running status压缩)
- 音轨结束事件:
FF 2F 00(元事件:轨道结束) - 回填MTrk块的长度字段
四、补充,和你电鼓相关
MIDI通道10(MIDI协议里是通道9,索引从0开始)固定打击乐通道:
每个音号对应不同鼓件:36底鼓、38军鼓、42闭踩镲、46开踩镲、49叮叮镲等。
所以DTX游戏、手卷鼓输出MIDI,就是输出Note On/Note Off到通道10。
五、举最小样例(极简MIDI示意)
四分音符TPQN=480,一个C4音符按下再松开。
- DeltaTime=0,NoteOn 通道1,音号60,力度100
- DeltaTime=480,NoteOff 通道1,音号60,力度80
版权属于:Joyber
本文链接:https://blog.qqvbc.com/default/1558.html
转载时须注明出处及本声明