MIDI格式

朋友的公司准备做的一个内容,我负责其中一个模块,该模块需要解析MIDI文件,然后生成另外一种格式。虽然也有开源的包可以用,不过那个包bug微多,而且已经停止维护很久了。(开发那个包的好像是个搞乐队,估计专心玩音乐去了吧)

花了1天多才写完,上点翻译内容,表示斯坦福大学的内容真心好理解啊

 

标准MIDI文件结构(译)

原文地址:http://www.ccarh.org/courses/253/handout/smf/

 

标准MIDI文件(Standard MIDI File 简称SMF)是由MIDI块(chunks)构成的。第一个MIDI块是Header块,接下来是一个或多个Track块。Header块包含整个MIDI文件的全局数据。每一个Track块都定义了一个逻辑音轨(track)

SMF = <header_chunk> + <track_chunk> [+ <track_chunk> ...]

一个块由三部分构成,与微软的RIFF文件类似(不同之处在于SMF是使用大端法存储(Big-endian),而RIFF是使用小端法(little-endian)),这三部分定义如下:

 1、  前四个字节是块IDHeader块是:”MThd”Track块是:”MTrk”

2、  下面四字节是无符号值,用来定义块中数据部分的长度

3、  最后则是块数据

Header

Header块包括块ID,长度,MIDI文件的格式信息,MIDI音轨(指逻辑音轨,即Track块个数)数量和MIDI最小时间单位长度信息。 

header_chunk = "MThd" + <header_length> + <format> + <n> + <division>

 “MThd” 4字节

标志Header块的字符,16进制表示为:0x4D546864。这4个字符出现在MIDI文件的开头,标志这是一个MIDI文件。

<header_length> 4字节

指示Header块中数据部分的长度(永远为6字节长,因为数据部分的三个字段均为2字节)。

<format> 2字节

0 = 单一音轨文件格式

1 = 多音轨文件格式

2 = 多歌曲文件格式(一组单一音轨的文件)

<n> 2字节

Header块后的Track块的数量。

<division> 2字节

间隔时间所对应的单位时间数(tick)。如果这个值为正,那么它标志着每一拍所对应的单位时间数。比如说,+96表示每拍对应96 ticks。如果这个值为负,间隔时间则对应SMPTE单位。

 

Track

Track块包括块ID,长度和事件信息(event data)

track_chunk = "MTrk" + <length> + <track_event> [+ <track_event> ...]

 “MTrk” 4字节

标志Track块开始

<length> 4字节

标志数据部分的长度

<track_event>

序列化的音轨事件

 

音轨事件(Track Event)

一个音轨事件由与上一事件的间隔时间和三种事件之一构成

 track_event = <v_time> + <midi_event> | <meta_event> | <sysex_event>

 <v_time>

一个变长值,用来表示与前一事件的间隔时间

<midi_event>

MIDI的通道事件,比如说音符开始(note-on)与音符结束(note-off)。其播放方法在MIDI装置中都相同。

<meta_event>

元事件

<sysex_event>

系统独有事件

 

元事件(Meta Event)

元事件不是MIDI数据(即不是用来控制MIDI播放的),包括前缀,类型标识,长度和数据部分

 meta_event = 0xFF + <meta_type> + <v_length> + <event_data_bytes>

 <meta_type> 1 字节

Type

Event

Type

Event

0x00

Sequence number

0x20

MIDI channel prefix assignment

0x01

Text event

0x2F

End of track

0x02

Copyright notice

0x51

Tempo setting

0x03

Sequence or track name

0x54

SMPTE offset

0x04

Instrument name

0x58

Time signature

0x05

Lyric text

0x59

Key signature

0x06

Marker text

0x7F

Sequencer specific event

0x07

Cue point

 <v_length>

变长值,表示数据部分长度

<event_data_bytes>

具体数据信息

系统高级事件(System Exclusive Event)

系统高级事件包括两种:

 sysex_event = 0xF0 + <data_bytes> 0xF7 or sysex_event = 0xF7 + <data_bytes> 0xF7

第一种中MIDI数据流应包含0xF0,第二种则可以省略。

 

可变长值:

SMF中,有一些值被表达为可变长的。这种可变长值是一种被压缩的格式:

一个可变长值使用每一个字节的低7位存储数据或者数据的一部分,最高位表示是否继续。只有可变长值的最后一字节的最高位为,其他均为1

 

例如:

   Variable Length Value        Real Value 

   0x7F                         127 (0x7F)

   0x81 0x7F                    255 (0xFF)

   0x82 0x80 0x00               32768 (0x8000)

你可能感兴趣的:(MIDI格式)