MIDI二进制文件格式简析
本文主要参考自Official MIDI Specifications
Chunks
每个MIDI文件由一系列chunk组成,每个chunk的前四个字节为魔数(magic number),是由四个ASCII字符所组成的类型标识。目前标准格式中已定义的chunk类型只有header和track两种,其魔数分别为"MThd"
和"MTrk"
,对于类型未被定义的chunk则应该被忽略。
每个chunk在其四字符类型之后紧跟一个32位无符号整数,意味这一chunk后续将要读入的字节个数,每个chunk已经读入的这八个字节不包含在内。
通常来说,一个MIDI文件中首先要存在一个header chunk,然后一系列track chunk紧随其后,格式大致如下:
MThd <length of header data>
<header data>
MTrk <length of track data>
<track data>
MTrk <length of track data>
<track data>
…
Header Chunks
在目前的标准中,header chunk长度固定为14,其由五个部分所组成:
<Header Chunk> = <chunk type> <length> <format> <ntrks> <division>
其中type固定为"MThd"
,format、ntrks、division均为16位,因此length固定为0x00000006
。
format指定了整个文件的组织结构,在当前的标准下,仅支持0x0000
、0x0001
、0x0002
这三种可能的值。
0 the file contains a single multi-channel track
1 the file contains one or more simultaneous tracks (or MIDI outputs) of a
sequence2 the file contains one or more sequentially independent single-track patterns
ntrks表示整个文件中track chunk的总个数,对于format为零的文件来说ntrks的值总是0x0001
。
最后的division表示了delta-times的含义,有metrical time和time-code-based time这两种形式,这取决于其最高位是否为零。
假如division最高位为零,那么就属于metrical time形式,这个16位无符号整数的意义为每个四分音符的ticks个数。否则属于time-code-based time形式,其低8位表示每帧的ticks个数,高8位为一个8位负数补码,有-24
、-25
、-29
、-30
这四种可能的值,其意义与SMPTE有关,以下内容摘抄自维基百科:
Sub-second timecode time values are expressed in terms of frames. Common supported frame rates include:
24 frame/sec (film, ATSC, 2K, 4K, 6K)
25 frame/sec (PAL (Europe, Uruguay, Argentina, Australia), SECAM, DVB, ATSC)
29.97 (30 ÷ 1.001) frame/sec (NTSC American System (US, Canada, Mexico, Colombia, etc.), ATSC, PAL-M (Brazil))
30 frame/sec (ATSC)
在这里可以发现,凭借division是完全不足以描述每个时间间隔的实际长度的。