MIDI文件格式分析
开头
每一个MIDI文件的开头都有如下一段内容,4d 54 68 64 00 00 00 06 ff ff nn nn dd dd
前四个字节是ASCII字符MThd 表示这是一个Midi文件,
下面四个字节是指明文件头描述部分的字节数,一共是6,所以一定是00 00 00 06
下面是剩余部分的含义
ff ff指定Midi的格式
00 00 表示单音轨
00 01表示多音轨同步(常见)
00 02表示多音轨不同步
nn nn表示轨道数
实际音轨倒数加上一个全局的音轨
dd dd指定基本时间
一般为120 (00 78)即一个四分音符的tick数,tick是MIDI中最小时间单位
例如下面
4d54 6864 0000 0006 0001 0003 01e0
表示这是一个MIDI文件 文件头描述部分占6字节 多音轨同步 一共3个音轨 基本时间是01e0(480)
内容
先来看全局音轨 全局音轨包括了歌曲的附加信息(比如标题和版权),歌曲速度和系统码等内容。
不论是全局音轨还是含有字符的音轨,都以4D 54 72 6B开头,表示”MTrk”后面跟着一个四个字节的整数,表示该音轨的字节数(不包括MTrk和本身的四个字节),然后是记录数据的地方。
每一个数据都有相同的结构:时间差+事件。
时间差
所谓时间差,就是指从前一个事件到这个事件的时间数,单位是tick。一个字节有 8 位,如果仅使用 7 位,它可以表示 0~127 这 128 个数,而剩下的一位,则用来作为标志。(这一位被放在了每个字节的最前端)。如果要表示的数在以上范围,则这个标志为 0,这时,一个7 位的字节可以表示 0~127tick。如果要表示的数 超出了这个范围(比如 240),则把标志设置成 1,然后记录下高 7 位,剩下的留给下一个字节,在该例中 240 可以分解成 128 1+112,这里的 1 就是第一个字节要记录的,加上标志位,应该为 10000001,即十六进制的 81;而 112 是下一个字节记录的,它的十六进制为 70:所以要表示 240 这个时间,要写成 81 70。 同理,如果要表示 65535tick,则可以先计算出65535=12823+1281127+1280127,然后得出结果:83 FF 7F。 由此,我们反过来也可以知道如何确定时间差:只要标志位为 0,则表示结束读取时间差。比如 82 C0 03 表示 12822+128164+1280*3=40963,如果基本时间为 120,则有 341:043 个四分音符。
以这种方式记录整数的字节称为动态字节,它根据记录的整数改变自身的长度,这在后面还要用到,所以 必须熟练计算。
事件
事件可以分为音符,控制器系统信息等几个种类,对于这些事件,都有统一的表达结构:种类+参数
对于一个音符,由于他的有效范围是0~127,所以直接用00~7F作为种类,也可以认为是个音符,比如3C表示中央C,而一个音符的最重要的参数是力度,比如,3C 64表示一个力度为100的中央C音符。
因为一个字节有8位,所以第一位如果置1,那么它就可以表示其他信息,
下表中,x 表示音轨 0~F,比如 81 表示松开第二轨的音符。
种类 | 参数(十六进制) | |
---|---|---|
字节 | 含义 | |
8x | 松开音符 | 音符(00~7F):松开的音符 |
力度:00~7F | ||
9x | 按下音符 | 音符(00~7F):按下的音符 |
力度:00~7F | ||
Ax | 触后音符 (Key After Touch) | 音符:00~7F |
力度:00~7F | ||
Bx | 控制器 | 控制器号码:00~7F |
控制器参数:00~7F | ||
Cx | 改变乐器 | 乐器号码:00~7F |
Dx | 触后通道 | 值:00~7F |
Ex | 滑音 | 音高(Pitch)低位:Pitch mod 128 |
音高高位:Pitch div 128 | |||
---|---|---|---|
F0 | 系统码 | 系统码字节数:动态字节 | |
系统码:不含开头的 F0,但包括结尾的 F7 | |||
FF | 其他格式 | 程式种类:00~FF | |
数据占用的字节数:动态字节 | |||
数据:个数由上一参数确定 | |||
00~7F | 上次激活格式的参数(8x、9x、Ax、Bx、Cx、Dx、Ex) | ||
节拍器时钟 | |||
一个四分音符包含的三十二分音符的个数 | |||
59 | 调号 | 02 | 升降号数:-7~-1(降号),0(C),1~7(升号) |
大小调:0(大调),1(小调) | |||
7F | 音序特定信息 | — | 音序特定信息 |
下表详细地列出了 FF 的详细情况,对于字节数由数据决定的情况,表中以“—”表示。
种类 字 节
字节 含义
00 设置轨道音序
数据 数
02 音序号 00 00~ FF FF
01
歌曲备注 文本信息 —
音轨文本 文本信息
02 歌曲版权
歌曲标题 —
03
— 版权信息
歌曲标题:用于全局音轨,第一次使用表示主标题,第二次表 示副标题
音轨名称 — 音轨名
04 乐器名称
— 音轨文本(同 01/2)
05歌词 —歌词
06 标记
07 开始点
2F 音轨结束标志
51 速度
— 用文本标记(Marker)
— 用文本记录开始点(同 01/2)
00 无
03 3字节整数,1个四分音符的微秒数
58节拍 04分子
分母:00(1),01(2),02(4),03(8)等
节拍器时钟 | |||
---|---|---|---|
一个四分音符包含的三十二分音符的个数 | |||
59 | 调号 | 02 | 升降号数:-7~-1(降号),0(C),1~7(升号) |
大小调:0(大调),1(小调) | |||
7F | 音序特定信息 | — | 音序特定信息 |