1. MIDI(Musical Instrument Digital Interface)概述
1.1. MIDI是编曲界最广泛的音乐标准格式,可称为“计算机能理解的乐谱”。(来自百度百科——MIDI)
2. MIDI文件格式
2.1. 一个MIDI文件格式是由一个头块和若干个轨道块组成的。
2.2. 头块的格式是“4D 54 68 64 00 00 00 06 ff ff nn nn dd dd”,其中“4D 54 68 64”是头块标记,后面紧接的4位表示头块的大小,现行的格式中头块固定为6个字节大小。“ff ff”指的是文件的格式,“nn nn”是MIDI文件中的轨道数,“dd dd”是每个4分音符tick数。
2.3. 每个轨道块的格式是由轨道头和若干事件组成的,轨道头的格式是“4D 54 72 6B xx xx xx xx”,其中“4D 54 72 6B”是轨道块标记,后面紧接的4位表示该轨道块的大小(不包括轨道头)。
2.5. 每个事件之前都会有一个delta-time,这个delta-time不同于头块里的delta-time,这里表示紧随其后的事件距离上一个事件的时间间隔,注意,如果是多轨同步,所有轨道块都是同时开始的,所以每个轨道块的第一个事件前面的delta-time都是距离开始的时间间隔。
3. delta-time(以tick为时间单位)
3.1. delta-time的格式:用多个字节表示,每个字节最高位是标志位(tick >= 128 ? 1 : 0),其余7位是数值,最后一个字节的标志位为0,所以读取时只需要逐个字节地读,读到最高位是0的字节停止。
3.2. delta-time的16进制转10进制:首先将每个字节最高位设为0,将每个字节分别转成10进制,再分别乘以128的n次方(n = delta-time字节长度 - 1 - i,i为第i个字节,从0开始)。
4. MIDI事件
4.1. MIDI事件格式:通常以一个字节(大于128)的命令码开始,如果delta-time结束之后的那个字节小于128,则是缺省命令码的MIDI事件(只有数据),沿用上个MIDI事件的命令码。命令码最常用的是8x(松开音符)、9x(按下音符)。命令码之后是对应的参数数据,8x、9x的参数都是两个字节:音符、速度(力度)。参数数据之后就是下一个事件的delta-time。
4.2. 获取音符事件就是从MIDI事件中获取。
6. 系统码事件
6.1. 系统码事件格式:固定开头:“f0”,以“f7”结尾。
6.2. 因为系统码事件在MIDI事件中不常见,所以没有深究。
7. 音符
7.1. 通过音符的16进制数求音符的符号(音名加音阶):假设音符是Ni,N是音名,i是音阶。公式:N = B mod 12;i = B div 12 - 1,其中B表示音符字节的10进制数。
7.2. N的10进制数值参照下表:
音名 |
C |
#C |
D |
#D |
E |
F |
#F |
G |
#G |
A |
#A |
B |
10进制数值 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
8. Java读取MIDI文件
9. MP3转MIDI文件
9.1. 可以用现有的软件来处理,比如cakewalk,widi等等。
9.2. 也可以到某些音乐网站上下载MIDI音乐,比如MidiShow。
10. 主要参考文献