我开始用 C++ 阅读 mp3 文件。
一切都很顺利,直到我阅读了 ID3-Tag 的规格。ID3v2-Header 中有一些关于其大小的信息存储在所谓的同步安全整数中。这是一个四字节整数,其中每个字节的最高有效位设置为零。
我发现了如何将它转换为普通整数,但我不能停止问自己为什么整数值以如此不必要的复杂方式存储。
我希望有人可以告诉我为什么以这种方式存储它。
要了解为什么使用同步安全整数,了解一点 MP3 数据的格式以及媒体播放器如何播放 MP3 文件会很有帮助。MP3 数据以一系列帧的形式存储在文件中。每个帧都包含一小部分以 MP3 格式编码的数字音乐以及一些关于帧本身的元数据。在每个 MP3 帧的开头,11 位(有时是 12 位)都设置为 1。这称为同步,这是媒体播放器在尝试播放 MP3 文件或流时寻找的模式。如果播放器找到这个 11 位序列,那么它就知道它找到了一个可以解码和播放的 MP3 帧。
如您所知,ID3 标签包含有关整个轨道的数据。ID3 标签——在 2.x 和更高版本中——位于文件的开头,甚至可以嵌入到 MP3 流中(尽管这并不经常这样做)。ID3 标签的头部包含一个 32 位大小的字段,表示标签中有多少字节。无符号 32 位整数可以容纳的最大值是 0xFFFFFFFF。因此,如果我们将 0xFFFFFFFF 写入 size 字段,我们将声明一个非常大的标签(实际上太大了)。当播放器尝试播放文件或流时,它会查找 MP3 数据帧的 11 位序列,但会在 ID3 标签头中找到 size 字段并尝试播放标签,因为 size 字段的前 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;
}
希望这可以帮助。
除了上述答案,我想从我的博客中添加一个页面:http: //phoxis.org/2010/05/08/synch-safe/
6.2. 同步安全整数
在标签的某些部分,使用非同步方案很不方便,因为事先不知道非同步数据的大小,这对于大小描述符来说尤其成问题。ID3v2 中的解决方案是使用同步安全整数,其中永远不会有任何错误同步。同步安全整数是保持其最高位(位 7)为零的整数,使八位中的七位可用。因此,一个 32 位同步安全整数可以存储 28 位信息。
来自http://www.id3.org/id3v2.4.0-structure
它与给定文档中所谓的“不同步”密切相关,您应该阅读整个第 6 章。所有这些都与最大限度地与各种软件和硬件的兼容性有关。