我开始用c ++阅读mp3文件。
一切顺利,直到我阅读了ID3-Tag的规格。 ID3v2-Header中有一些关于它的大小存储在所谓的Synchsafe Integer中的信息。这是一个四字节整数,其中每个字节的最高有效位设置为零。
我发现了如何将它转换为ordenaty整数,但我无法停止问自己为什么整数值以这种不必要的复杂方式存储。
我希望有人可以告诉我为什么会这样存储。
答案 0 :(得分:23)
要理解为什么使用同步安全整数,了解一下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标签标题中找到大小字段并尝试播放标记,因为大小字段具有前一个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;
}
希望这有帮助。
答案 1 :(得分:3)
除了以上答案,我还想在我的博客中添加一个页面:http://phoxis.org/2010/05/08/synch-safe/
答案 2 :(得分:0)
6.2。 Synchsafe整数
在标签的某些部分使用非同步方案是不方便的,因为预先不知道非同步数据的大小,这对于大小描述符尤其有问题。 ID3v2中的解决方案是使用synchsafe整数,其中永远不会有任何错误的同步。 Synchsafe整数是整数,它将最高位(第7位)归零,从而使8位中的7位可用。因此,32位同步整数可以存储28位信息。
来自http://www.id3.org/id3v2.4.0-structure
它与他们在给定文档中称为“非同步”的内容紧密相关,您应该阅读整个第6章。所有这些都与最大限度地兼容各种软件和硬件有关。