MIDI文件格式(一)

在每个 Midi 文件的开头都有如下内容它们的十六进制代码为:“4d 54 68 64 00 00 00 06 ff ff nn nn dd dd”。

前四个是ASCII字符“MTrk”,用来鉴别是否为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 中的最小时间单位

以上是MIDI文件的文件头。

MIDI数据是若干个格式相同的子数据构成。这些子数据在多音轨的格式中记录了一个轨道的所有信息。多加一个音轨,就简单地把数据追加在前一音轨的后面就可以了,不过不要忘记更改文件头中的 nn nn(轨道数)。

接着就是记录数据的地方了:

 

记录的数据:

每一个数据都有相同的结构:时间差+事件

1. 时间差

指前一个事件到该事件的时间数,单位是tick(MIDI的最小时间单位)

以这种方式记录整数的字节称为动态字节,它根据记录的整数改变自身的长度。

表示 65535 tick:

MIDI文件格式(一)_第1张图片

第一行:当128的次方不为0时,第一行都是1000 0000;只有当次数为0时,才为0000 0000。

第二行:为128乘数的2进制表示,有8位。

最后结果为相加之后的十六进制表示。

其结果为:83 FF 7F

 

若要通过结果确定时间差,何时截止?发现,当红圈表示的第一位为0时,结束。

即十六进制表示的第一位小于8,即为0~7时为结束。

MIDI文件格式(一)_第2张图片

如83 CF C0 33 6D 3E 表示:(83 CF C0 33 )|(6D 3E)

方法一(简):

对于“XY”,当X属于8~F:(X - 8)*16 + Y;当X属于0~7:X*16 + Y;

方法二(繁)(其实就是方法一的原理):

2. 事件

大体可分为音符、控制器、系统信息。这些事件都有统一的表达结构:种类+参数

对于一个音符,由于它的有效范围是 0~127,所以直接用 00~7F 作为“种类”,可以认为是个音符,比如 3C 表示中央 C。而一个音符的最重要的参数是力度(也叫速度:velocity)。比如,3C 64 表示一个力度为十进制100的中央C音符。

(本句出自https://blog.csdn.net/meicheng777/article/details/52054838)

事件:

字节 含义 参数(十六进制)
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)

 

 

你可能感兴趣的:([C++],MIDI)