读取MIDI文件(C):0x00出现在var-length值结束之后

时间:2012-12-06 12:21:52

标签: c hex midi binaryfiles file-format

我试图写一些函数来读取MIDI文件。我指的是许多提供规范的网站,但主要是这一个:http://www.sonicspot.com/guide/midifiles.html

我在MIDI文件上测试了我下载的Super Mario Bros主题,并且我得到了一些意想不到的数据。可能是文件格式错误,但我认为我更有可能做错了。以下是我遇到问题的数据(来自十六进制编辑器)以及我所知道的我知道的

4D 54 72 6B 00 00 00 19 00 FF 51 03 05 7B 71 00 FF 58 
|---------| |---------| || || || |------| || ||
    MTrk    Chunk size  || || ||  Tempo   || ||
             (25 bytes) || || ||(ms per   || ||
                        \/ || ||1/4 note) || ||
                VLen value || ||          \/ ||
          (Event at time 0)|| ||  VLen value ||
                           \/ || (event at   ||
                 Beginning of ||  time 113)  ||
                 meta-event   ||             ||
                              \/             \/
                 Meta-event type:           ????
                      set tempo

正如您所看到的,如果0x00之前的所有内容都是正确的,那么它在那里做了什么?之前的VLen值具有二进制值01110001,因此不期望VLen值的另一部分,因此,AFAIK,应该是事件类型。但是,没有与0x0关联的事件类型。谁能看到我出错的地方?

1 个答案:

答案 0 :(得分:5)

我发现了问题:元事件代码(在我的情况下是0x51)由块大小继续进行,就像普通事件一样。我不这么认为的原因是,对于set tempo元事件,速度数据大小始终为3.因此51 03 05 7B 71实际上是设置的速度事件代码(51),即节奏的大小数据(03)然后是实际速度(05 7B 71),然后00只是另一个可变长度值,告诉我下一个事件是在时间0。

我希望这有助于某人。我还找到了一个更好的MIDI格式文档,使其更清晰:http://www.omega-art.com/midi/mfiles.html