为什么MP3文件使用同步安全整数?

11

我开始用C++读取mp3文件。

一切都很顺利,直到我读到ID3标签的规格说明。在ID3v2头部中有一些关于其大小的信息存储在所谓的同步安全整数中。这是一个四字节的整数,每个字节的最高有效位都设置为零。

我找到了如何将其转换为普通整数,但我想知道为什么要以这种不必要的复杂方式存储整数值。

我希望有人能告诉我为什么要以这种方式存储。

3个回答

31
为了理解为什么使用同步安全整数,有必要了解一下MP3数据格式以及媒体播放器如何播放MP3文件。MP3数据以帧的形式存储在文件中。每个帧包含一小段数字音乐编码为MP3格式以及有关帧本身的一些元数据。每个MP3帧开头都有11位(有时是12位)全设置为1。这被称为同步,并且是媒体播放器在尝试播放MP3文件或流时寻找的模式。如果播放器找到这个11位序列,那么它就知道已经找到了一个可以解码和回放的MP3帧。

参见: www.id3.org/mp3Frame

正如你所知,ID3标签包含有关整个曲目的数据。ID3标签 - 在2.x版本及更高版本中 - 位于文件开头,甚至可以嵌入MP3流中(尽管这不经常发生)。ID3标签的标题包含一个32位大小字段,该字段指示标签中有多少字节。无符号32位整数可以容纳的最大值是0xFFFFFFFF。因此,如果我们将0xFFFFFFFF写入大小字段,则声称拥有一个非常大的标签(实际上太大)。当播放器尝试播放文件或流时,它寻找MP3数据帧的11位序列,但是找到了ID3标签标题中的大小字段,并尝试播放标签,因为大小字段的前11位已设置。这通常听起来不太好,这取决于您的音乐口味。解决方案是创建一个整数格式,其中不包含所有1的11位序列。因此出现了同步安全整数格式。

可以使用类似以下内容的代码将同步安全整数转换为C/C ++中的整数:

int ID3_sync_safe_to_int( uint8_t* sync_safe )
{
    uint32_t byte0 = sync_safe[0];
    uint32_t byte1 = sync_safe[1];
    uint32_t byte2 = sync_safe[2];
    uint32_t byte3 = sync_safe[3];

    return byte0 << 21 | byte1 << 14 | byte2 << 7 | byte3;
}
希望这可以帮助到你。

2
非常感谢。我以为我永远都得不到它。 - the_mario
此外,这样做的原因是因为 MP3 不是创建时考虑到元数据标签的。ID3 后来问世,并不得不找到一种方法来在现有的 MP3 限制内工作,而不破坏任何东西。 - hippietrail

3

0
6.2. 同步安全整数
在标签的某些部分中,使用不同步方案是不方便的,因为未同步数据的大小事先是未知的,这在使用大小描述符时尤其棘手。ID3v2 中的解决方案是使用同步安全整数,其中永远不会有任何错误的同步。
同步安全整数是指保持其最高位(第 7 位)为零的整数,使得八位中有七位可用。因此,32 位同步安全整数可以存储 28 位信息。
来自http://www.id3.org/id3v2.4.0-structure 这与所提供文档中所称的“非同步化”密切相关,您应该阅读整个第 6 章。所有这些都与最大化与各种软件和硬件的兼容性有关。

我不明白为什么大小应该是未知的。虽然有不同大小的数据字段,但在规格说明书中描述了特定信息存储在文件中的位置以及这些信息的大小。 - the_mario

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接