文章目录
- 一、从 MIDI 文件中可以获取的信息
- 1、音符速度设置事件
- 2、拍号设置事件
- 3、文件头基本时间
- 二、节拍时值计算
- 三、小节时值计算
一、从 MIDI 文件中可以获取的信息
MIDI 时间标志原始信息来源 , 就是 MIDI 文件中的 Meta 事件 ;
Meta 事件 以 FF 开始 , 其格式如下 :
FF xx nn dd
- FF : 表示 Meta 事件的 开始标志 ;
- xx : 表示 该 Meta 事件的类型 , 如 03 类型表示该 Meta 事件是 " 音符速度设置事件 " , 04 类型表示该 Meta 事件是 " 拍号设置事件 " ;
- nn : 表示 该 Meta 事件有多少个字节 , 该数值可以是可变长度的数值 , 一般情况下只占
字节 ;
- dd : Meta 事件的实际数据 , 有 nn 个字节 ;
MIDI 文件中的 " 音符速度设置 Meta 事件 " , " 拍号设置 Meta 事件 " , " 文件头的 基本时间 " , 决定了该 MIDI 曲子的事件标志 ;
1、音符速度设置事件
参考 【BLE MIDI】MIDI 文件格式分析总结 ★★★ 八、FF 51 03 四分音符时长 博客章节 , 可以知道 , FF 51 03
是时间设定的标志 ;
FF 51 03 07 A1 20
: 32 ~ 37 字节 , 音符速度标志 ;
FF 51 03
是音符速度标志位 , 后面的 07 A1 20
3 字节是一个数字 , 代表 四分音符 的时长 , 单位是微秒 ;
07 A1 20
对应十进制数是 500000 , 五十万 , 也就是一个四分音符是 50 万微秒 ;
在之前的 【BLE MIDI】MIDI 文件格式分析 ( MIDI 文件头解析 | MIDI 文件头标识 | MIDI 文件头长度 | MIDI 文件格式 | MIDI 轨道个数 | 基本时间 ) 二、MIDI 文件头解析 5、基本时间 博客章节 解析到一个四分音符有 480 个 tick ;
此时可以计算出每个 tick 的时长为
微秒 ;
再回顾下 delta-time 的计算 :
8E 7E
对应的二进制位数为 : 1000 1110 0111 1110
第一个字节 8E 对应的二进制数据位 1000 1110 , 其中第七位的 1 表示这是 delta-time 的高位字节 , 后面的 000 1110 是实际的数值数据 ;
第一个字节 7E 对应的二进制数据位 0111 1110 , 其中第七位的 0 表示这是 delta-time 的低位字节 , 后面的 111 1110 是实际的数值数据 ;
则该 delta-time 的实际数据是 000 1110 111 1110 , 重新组合后为 111 0111 1110 , 该 delta-time 的值是 1918 , 也就是 1918 个 tick 数 ;
上述的 delta-time 是 1918 个 tick , 对应的时间是
微秒
2、拍号设置事件
FF 58 04 04 02 18 08
: 39 ~ 45 字节 , 拍子记号 ;
FF 58 04 是拍子记号的标志 ;
04 02 18 08 分别表示 :
- 04 : 拍子记号的分子 ;
- 02 : 拍子记号分母标志 , 这里的值是 2 的次幂值 , 如当前设置的值是 2 , 则拍子记号的分母是
, 分母是 4 ;
- 18 : 每个 MIDI 时钟包含的 tick 数 ; 标准值是 24 , 一般不会改变 ;
- 08 : 每 24 个 MIDI 时钟 , 对应的 32 分音符的数目 ; 标准值是 8 , 一般不会改变 ;
后面的 00 是 delta-time , 与下一个 midi 事件间隔的 tick 数 ;
delta-time 参考 【BLE MIDI】MIDI 文件格式分析 ( MIDI 轨道分析 | MIDI 轨道头 | MIDI 轨道长度 | delta-time 间隔 ) 四、delta-time 间隔 博客章节 ;
3、文件头基本时间
参考 【BLE MIDI】MIDI 文件格式分析总结 ★★★ 二、MIDI 文件头解析 5、基本时间 博客章节 ;
01 E0
: 12 ~ 13 字节 , 用于指定基本时间 ;
2 个字节 , 要拆分成 3 部分 , 最高位 ( 第 15 位 ) 作为标识位 , 第 8 ~ 14 位 作为一部分 , 第 0 ~ 7 位 作为一部分 ;
由于是大端格式排列 , mid 文件第 12 字节 ( 低地址 ) 是 高位 , mid 文件第 13 字节 ( 高地址 ) 是低位 ;
01 E0
的二进制形式如下 : 0000 0001 11110 0000 ;
最高位 0000 0001 11110 0000 是 0 , 红色的是最高位 , 表示当前 代表的事件格式是 类型1 , 第 0 ~ 14 位 代表的是 四分音符的 tick 数 ;
十六进制 01 E0
对应的十进制数字是 480 , 也就是说一个四分音符有 480 tick ;
tick 是时间单位 , 这是 mid 文件中计算时间的最基本单位 ;
二、节拍时值计算
在文件头的基本时间中 , 可以获取到每个 四分音符的 tick 或 pulse 数 ;
在 Meta 事件 音符速度设置事件 中 , 可以获取到每个 四分音符的 微秒数 ;
此时可以将 tick 或 pulse 值 , 与 现实的 微秒 时间 对应起来 ;
如果要计算具体的小节位置 , 需要结合拍号来计算 ,
上面只是获取了 四分音符 的时值信息 , 即 四分音符的 tick 数 , 以及 四分音符 的 微秒数 ;
如果要计算 节拍 时间 , 要看 拍号中的分母值 ,
- 如果分母是
, 则每拍的时值 直接使用 四分音符 时值乘以
;
- 如果分母是
, 则每拍的时值 就是 四分音符的时值 ;
- 如果分母是
, 则每拍的时值 直接使用 四分音符 时值除以
;
三、小节时值计算
每个小节的时值 就是 每拍的时值 乘以 拍号分子 ;