|
发表于 2016-7-16
|
标准文件
MIDI文件包含一个或更多MIDI块与每个事件的时间信息。它支持歌曲、序列和音轨结构,拍子和拍号信息。 音轨名字和其他描述信息也可以与MIDI信息一同存储。 这个格式支持多条音轨、多个序列。这种格式可以允许用户从一个音轨移向另一个音轨。
用于MIDI文件的8位二进制的数据块可以在一个高效率的传输的MIDI二进制文件中,分解可以存储为7位数据,或被转换成其他的ASCII或者被翻译为一个文本文件。
1. MIDI序列文件由块组成。 每个块4个字节,有32位长度。 在苹果机上,数据通过在文件的数据叉,或者在剪贴板上进行传输。 (在Macintosh这个格式的文件类型是" Midi") 块结构允许被忽略跳过。
这里定义了块的二种类型: 文件头块和音轨块。 文件头块提供关于整个MIDI文件的最小数量信息。 音轨块包含的MIDI数据序列也许包含16条MIDI通道的信息。 使用多个音轨块,就可以用多条音轨、多个MIDI序列、谱式和歌曲。 MIDI文件总是以文件头块开始,紧随其后的是一个或多个音轨块。
MTrk块类型是存放实际歌曲数据的地方。它是MIDI事件(和非MIDI事件)的序列。在MTrk块的有些数字是以叫可变长的数量的形式进行存储的。 这些数字首先每个字节用7位,最高位不是有效位。 除最后一位之外的所有字节,最高位设为1;最后一个字节最高位设为0。 如果数字在0和127之间,它能正确地表示为一个字节。 这作为可变长的数量代表的数字的有些例子:
数字(十六进制) 变长表示法(十六进制)
00000000 00
00000040 40
0000007F 7F
00002000 C0 00
00003FFF FF 7F
00004000 81 80 00 00
100000C0 80 00
001FFFFF FF FF 7F
00200000 81 80 80 00
08000000 C0 80 80 00
0FFFFFFF FF FF FF 7F
允许的大数是0FFFFFFF,这是以可变长表示法表示的32位的最大数字。 理论上,大数是有可能的,但是实际中不必要。
MTrk块的句法: = + = < 经过的时间> 被作为一个可变长的量存储。 它代表以下事件之前所要经过的时间。 如果在音轨的第一个事件发生在音轨的开始,或者,如果二个事件同时发生,使用Δt的零。 Δt总是存在。 Δt的具体时间单位,在文件头块上指定。
=|<元event> | < MIDI event> 是所有MIDI通道消息。 使用连续状态时: 状态位也许在第一个事件以后被省去。 在文件的第一个事件必须指定状态。 Δt没有被认为是事件: 它是格式的整体部分。
<元event> 指定非MIDI信息。有用对这个格式,有这样的句法:
FF 所有阶事件从FF开始,然后有事件类型(总是少于128),然后有作为一个可变长的数量被存放的数据的长度,然后是数据。 如果没有数据,长度是0。
< sysex event> 使用指定MIDI系统专属消息,或者作为" escape" 指定将被传送的任何任意字节。 不幸地是,一些合成器制造者指定他们的系统专属消息将被作为小包传送。 每个小包作为一则整个语法系统专属消息的部分,但是他们被传送的时间是很重要的。这样的例子是在CZ补丁传送的字节或者FB-01' s " 系统独家新闻" 中,可以传送部分数据。 为了能处理像这样的情况, 两个形式的被提供了:
F0 <长度> <数据>
F7 <长度> <数据>
在两种情况下, 长度被作为一个可变长的数量存放,等于跟随它的字节数,不包括本身或消息类型(F0或F7),但是包括跟着的所有字节,包括所有在意欲被传送的信息末端的F7。 绝大多数的系统专属消息将使用F0格式。 例如,被传送的消息F0 43 12 00 07 F7在MIDI文件将被存储为F0 05 43 12 00 07 F7。 如上所述,所有信息要求在末端包含F7,以便MIDI文件的处理程序知道它读了全部的信息。 对于特别的情况,当一则唯一的系统专属信息被分开成多段,分到不同的时间传送时, 小包除了最后一个都以F7结束。 不能在多个小包之间传递任何其他的系统专属信息。 例如:
假设字节43 12 00将首先被传送到F0,紧随着200个时间单位的延迟,再紧随着由字节43 12 00 43 12 00组成的数据,再紧随着100各时间单位的延迟,再紧随着由字节43 12 00 F7组成的数据,这在MIDI文件是这样的: F0 03 43 12 00 81 48
200个单位的Δt
81 48 F706 43 12 00 43 1200 64
100个单位的Δt
64 F7 04 43 12 00 F7
F7事件也许也使用作为" escape" 传送任何字节,包括实时字节、歌曲名或者MIDI时间代码,在这个规格通常没有被规定。
文件头块
在文件初的文件头块指定在文件中关于数据的一些基本信息。数据部分包含三个16位的字段,首先被存放高位字节(当然)。 这里有完整的块的句法:
<块类型><块长度><格式><音轨数><分区>
如上所述,块类型是四个ASCII字符' MThd' ; 随后的长度是一个6 (高位优先的32位数字表示法)。 格式,是指定文件的整体组织。
格式的只有三种值,指定三种格式:
0 文件包含一条唯一的多通道音轨
1 文件包含一个或更多同时的音轨
2 文件包含一个或更多独立的音轨,相继进行播放
音轨数,是文件中音轨块的数量。
分区,是在文件的Δt之中1代表的是一秒的多少分之一。
格式0 ,多通道的音轨,是最容易转换的数据。应用格式1 的MIDI文件可以很容易转换成这种格式。声音是最重要的东西,格式并不重要。这种转换是非常应该的,这可以化繁为简。
MIDI文件有可以表达的节奏和拍号的信息。对于0的文件格式,节奏,将分散的存储;对于格式1,节奏必须(在0.04版起)一起储存,作为第一条音轨。这个规定是合理的。
所有的MIDI文件,应指定节奏和拍号。如果他们不这样做,拍号假设为4 / 4 ,节奏和节拍120每分钟。在格式0中 ,这些元事件应该在开头。在格式1 中,这些元事件应包含在第一个音轨中。在格式2 中,每一独立的音轨,应至少包含一条拍号和节奏的信息。
元事件
不是每个程序,都必须支持每一个元事件。元事件最初的定义包括:
序列数
FF 00 02 ssss
这一类事件,必须发生在音轨的开头,在任何非零时间后发生的事件或可传送的MIDI信息之前,用于指定序列的数目。序列数对应在这条音轨的序列数。在一个格式0或1 MIDI文件,其中只包含一个序列,这个数字应包含在第一个音轨。
文字事件
FF 01 长度 文字
任何数量描述任何事情的文字。在音轨开头放上这条音轨的相关的所有信息是很好的,这有助于日后查看。文本事件也可能发生在其他时间,被用来作为歌词。在此事件中文本应用可打印的ASCII字符进行书写。
元事件类型01到0F的是预留给各种类型的文本使用的,但使用的目的各不相同:
版权公告
FF 02 长度 文本
载有版权声明,作为打印ASCII文本。文本中应包含字符( c ),版权所有的时间,版权所有者。如果几段音乐是在同一个MIDI文件中,所有的版权声明应放在一起,把它放在文件的开头。这个事件应该是第一个事件,在时间0放在第一条音轨块。
序列/音轨的名称
FF 03长度 文本
乐器名称
FF 04长度 文本
说明该类型的乐器将用于在这一条音轨中使用。
歌词
FF 05长度 文本
写明歌词。一般来说,每个音节将是一行单独的歌词,应该写清时间
标记
FF 06长度 文本
通常在一个格式0的音轨,或在格式1的第一个音轨。
注释点
FF 07长度 文本
描述一些在这一点上发生在电影或视频屏幕或舞台的动作或事件
音轨终止
FF 2F 00
此事件必须的,以便确定的结束点。
设定速度,以毫秒(ms)为单位,是四分音符的时值
FF 51 03 tttttt
这个事件可以精确的写清楚这条音轨的速度。 用每拍所占的时间而不是单位时间内的拍数表示速度,使得依据一个基于时间的同步协议(例如SMPTE时间代码或MIDI时间代码)实现时间的绝对同步成为可能。 这种准确性使四分钟左右的曲子在每分钟的120拍下结束时,时间误差在500 微秒之内。
SMPTE 时间同步
FF 54 05 hr mn se fr ff
这一事件,如果存在的话,将指定某一个特定事件开始的SMPTE时间。它应出现在音轨的开头,在任何非零时间后发生的事件或可传送的MIDI信息之前。
拍号标记
FF 58 04 nn dd cc bb
因此,完整的 6 / 8拍号应该表示为
FF 58 04 06 03 24 08
三十二分音符。
谱号信息
FF 59 02 sf mf
sf指明乐曲曲调中升号、降号的数目。例如,A大调在五线谱上注了三个升号,那么sf=03。又如,F大调,五线谱上写有一个降号,那么sf=81。 也就是说,升号数目写成0x,降号数目写成8x
mf指出曲调是大调还是小调。大调mf=00,小调mf=01
对于序列器的元数据
FF 7F长度 数据
特殊要求,尤其是时序可能会使用此事件类型:第一个字节或字节的数据是一个制造商的ID 。
作为一个例子, 把一个MIDI文件摘录如下所示。
内容的MIDI流所代表的这个例子,细分在这里:
Δt(十进制) 事件号(十六进制) 其他数据(十进制) 说明
0 FF 58 04 04 02 24 08
0 FF 51 03 500000
0 C0 5 通道1, 音色5
0 C1 46 通道2, 音色46
0 C2 70 通道3, 音色70
0 92 48 96 通道3 开始弹奏C2, 用力
0 92 60 96 通道3 开始弹奏C3, 用力
96 91 67 64 通道2 开始弹奏G3, 用力
96 90 76 32 通道1 开始弹奏E4, 钢琴
192 82 48 64 通道3 停止弹奏C2, 标准
0 82 60 64 通道3 停止弹奏C3, 标准
0 81 67 64 通道2 停止弹奏G3, 标准
0 80 76 64 通道1 停止弹奏E4, 标准
0 FF 2F 00 结束
整个格式0 的MIDI文件的内容,首先,文件头块:
4D 54 68 64 MThd
00 00 00 06 块长度
00 00 格式 0
00 01 一个音轨
00 60 一个MIDI时间间隔等于96分之一秒
接着,音轨块,
4D 54 72 6B MTrk
00 00 00 3B 音轨长度(59字节)
时间 事件
00 FF 58 04 04 02 18 08 拍号4/4
00 FF 51 03 07 A1 20 速度
00 C0 05
00 C1 2E
00 C2 46
00 92 30 60
00 3C 60
60 91 43 40
60 90 4C 20
81 40 82 30 40
00 3C 40
00 81 43 40
00 80 4C 40
00 FF 2F 00 终止
类似的,可以把这个文件写成1格式。
MIDI格式在网络传送中,通常采用7位数据传送方式,这样可以大大提高传输速度。
MIDI格式由于体积很小,非常便于传送;而且,由于它很有利于创作音乐,是很多作曲家在创作初期的首选。
MIDI格式由于其特殊的记录方式,受硬件影响较大。
MID格式文件很容易被人误解,很多人在电脑上直接播放MID后总会说“MID音质特别差”。这里再次要强调一遍,MID文件不是音频文件,它的作用只相当于一个文本文档,记录了音乐该如何进行。MIDI回放音色完全取决于声卡,之所以在windows系统上播放MID不能取得良好效果是因为系统自带的音色库比较简单。如果需要得到很不错的音色,则另需加装专业软音源插件,一块专业声卡也是必不可少的。
具体实例
4d 54 68 64 // “MThd”
00 00 00 06 // 长度always 6,后面有6个字节的数据
00 01 // 0-单轨; 1-多规,同步; 2-多规,异步
00 02 // 轨道数,即为”MTrk”的个数
00 c0 // 基本时间格式,即一个四分音符的tick数,tick是MIDI中的最小时间单位
4d 54 72 6b // “MTrk”,全局轨为附加信息(如标题版权速度和系统码(Sysx)等)
00 00 00 3d // 长度
00 ff 03 // 音轨名称
05 // 长度
54 69 74 6c 65 // “Title”
00 ff 02 // 版权公告
0a // 长度
43 6f 6d 70 6f 73 65 72 20 3a // “Composer :”
00 ff 01 // 文字事件
09 // 长度
52 65 6d 61 72 6b 73 20 3a // “Remarks :”
00 ff 51 // 设定速度xx xx xx,以微秒(us)为单位,是四分音符的时值
03 // 长度
07 a1 20 // 四分音符为 500,000 us,即 0.5s
00 ff 58 // 拍号标记
04 // 长度
04 02 18 08 // nn dd cc bb 拍号表示为四个数字。nn和dd代表分子和分母。分母指的是2的dd次方,例如,2代表4,3代表8。cc代表一个四分音符应该占多少个MIDI时间单位,bb代表一个四分音符的时值等价于多少个32分音符。 因此,完整的 6 / 8拍号应该表示为 FF 58 04 06 03 24 08 。这是, 6 / 8拍号( 8等于2的三次方,因此,这里是06 03),四分音符是32个MIDI时间间隔(十六进制24即是32),四分音符等于8个三十二分音符。
00 ff 59 // 谱号信息
02 // 长度
00 00 // sf mf 。sf指明乐曲曲调中升号、降号的数目。例如,A大调在五线谱上注了三个升号,那么sf=03。又如,F大调,五线谱上写有一个降号,那么sf=81。也就是说,升号数目写成0x,降号数目写成8x 。mf指出曲调是大调还是小调。大调mf=00,小调mf=01。
00 ff 2f 00 // 音轨终止
4d 54 72 6b // “MTrk”,普通音轨
00 00 01 17 // 长度
00 ff 03 // 00: delta_time; ff 03:元事件,音轨名称
06 // 长度
43 20 48 61 72 70 // “C Harp”
00 b0 00 00 // 00:delta_time; bn:设置n通道控制器; xx:控制器编号; xx:控制器值。此处为设置0通道0号控制器值为0。
00 b0 20 00 // 此处为设置0通道32号控制器值为0。
00 c0 16 // 00:delta_time; cn:设置n通道音色; xx:音色值。此处为设置0通道音色值为22 Accordion 手风琴。
84 40 b0 65 00 // 此处为设置0通道101号控制器值为0。
00 b0 64 00 // 此处为设置0通道100号控制器值为0。
00 b0 06 18 // 此处为设置0通道6号控制器值为0。
00 b0 07 7e // 此处为设置0通道7号控制器(主音音量)值为126。
00 e0 00 40 // 00:delta_time; en:设置n通道音高; xx yy:各取低7bit组成14bit值。此处为设置0通道音高值为64。
00 b0 0a 40 // 此处为设置0通道7号控制器(主音音量)值为126。
00 90 43 40 // 00:delta_time; 9n:打开n通道发音; xx yy: 第一个数据是音符代号。有128个音,对MIDI设备,编号为0至127个(其中中央C音符代号是60)。 第二个数据字节是速度,从0到127的一个值。这表明,用多少力量弹奏。 一个速度为零的开始发声信息被认为,事实上的一个停止发声的信息。此处为以64力度发出67音符。
81 10 80 43 40 // 81 10:delta_time; 8n:关闭n通道发音; xx yy: 第一个数据是音符代号。有128个音,对MIDI设备,编号为0至127个(其中中央C音符代号是60)。 第二个数据字节是速度,从0到127的一个值。这表明,用多少力量弹奏。 一个速度为零的开始发声信息被认为,事实上的一个停止发声的信息。此处为以64力度关闭67音符。
00 90 43 40
30 80 43 40
00 90 45 40
81 40 80 45 40
00 90 43 40
81 40 80 43 40
00 90 48 40
81 40 80 48 40
00 90 47 40
83 00 80 47 40
00 90 43 40
81 10 80 43 40
00 90 43 40
30 80 43 40
00 90 45 40
81 40 80 45 40
00 90 43 40
81 40 80 43 40
00 90 4a 40
81 40 80 4a 40
00 90 48 40
83 00 80 48 40
00 90 43 40
81 10 80 43 40
00 90 43 40
30 80 43 40
00 90 4f 40
81 40 80 4f 40
00 90 4c 40
81 40 80 4c 40
00 90 48 40
81 40 80 48 40
00 90 47 40
81 40 80 47 40
00 90 45 40
83 00 80 45 40
00 90 4d 40
81 10 80 4d 40
00 90 4d 40
30 80 4d 40
00 90 4c 40
81 40 80 4c 40
00 90 48 40
81 40 80 48 40
00 90 4a 40
81 40 80 4a 40
00 90 48 40
83 00 80 48 40
01 b0 7b 00 // 00:delta_time; bn:设置n通道控制器; xx:控制器编号; xx:控制器值。此处为设置0通道123号控制器(关闭所有音符)值为0。
00 b0 78 00 // 00:delta_time; bn:设置n通道控制器; xx:控制器编号; xx:控制器值。此处为设置0通道120号控制器(关闭所有声音)值为0。
00 ff 2f 00 // 音轨终止 |
|