1

根据本教程,我正在尝试编写一个 C++ 程序,该程序以十六进制格式读取 MIDI 并推断必要的数据。在轨道块信息中,第一个信息是您正在查看轨道“MTrk”的事实。第二个 4 字节指的是块大小。

据我了解,块大小是指下一个轨道块开始之前的字节数,或者文件结尾。但是,在我一直使用的 midi 文件中,我的块大小通常太小。也就是说,假设块大小为 40 字节:下一个“MTrk”直到当前一个字节之后的大约 70 个字节才会出现(我确实考虑了“MTrk”和块大小本身不是块大小的一部分)。那么,这些额外的 30 个字节是什么?我应该截断块大​​小之后出现的字节吗?或者我应该忽略块大小并继续阅读,直到遇到下一个轨道(或 FF2F00,表示轨道结束)?

在读入一个 MIDI 文件后,我记录了以下内容作为输出:

4D546864000000060001000300604D54726B0000000B00FFFFFFFF510306FFFFFF8A1B00FFFFFFFF2F004D54726B

下面我将有意义的部分分开:

4D546864
00000006
0001
0003
0060 

(标题结束)

4D54726B
0000000B

(块大小 = 11 个字节)

00FFFFFFFF510306FFFFFF8A1B00FFFFFFFF2F00

(但在这里我们看到 20 个字节)

4D54726B

是我使用的 MIDI 文件。

4

1 回答 1

0

我从提供的链接下载了文件,对我来说看起来很正常。让我们分解它定义的块。

第一个块的大小为 6 个字节:00 01 00 03 60,这告诉我们它是一个 MIDI 类型 1 文件,有 3 个轨道,时间划分为 96

下一个块(MTrk)的长度为 11 个字节:00 ff 51 03 06 8a 1b 00 ff 2f 00. 在这种情况下,它只包含一个用于速度的 MIDI 元事件,然后是一条音轨结束消息。

之后是第二个轨道,它的长度为02 92字节(以 10 为基数为 658)。一些定义轨道名称和乐器的 MIDI 元事件出现,然后是常规 MIDI 数据。终于来了最后一首……

我不确定您的计数到底在哪里,您确定您没有将 4 字节标头(即 MTrk)与块中的总字节数进行计数吗?块长度不包括名称或长度所需的 8 个字节。

为了将来参考,该hexdump实用程序对于查看此类文件非常有用,尤其是使用-C. 对于此文件,它将显示如下数据:

$> hexdump -C ArminvanBuurenFerryCorsten_-_Bruteversion4__iCarroller_20130206094335.mid 
00000000  4d 54 68 64 00 00 00 06  00 01 00 03 00 60 4d 54  |MThd.........`MT|
00000010  72 6b 00 00 00 0b 00 ff  51 03 06 8a 1b 00 ff 2f  |rk......Q....../|
00000020  00 4d 54 72 6b 00 00 02  92 00 ff 03 0c 53 61 77  |.MTrk........Saw|
... etc.
于 2013-10-29T16:51:48.107 回答