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

ben*_*wad 5 c midi hex file-format binaryfiles

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

我一直在我下载的超级马里奥兄弟主题的MIDI文件上测试它,我得到了一些意想不到的数据.可能是文件格式错误,但我认为更有可能是我做错了.下面是我遇到的麻烦的数据(从十六进制编辑器),什么我我知道这件事情:

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
Run Code Online (Sandbox Code Playgroud)

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

ben*_*wad 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