为什么MP3文件使用Synchsafe整数?

问题描述 投票:9回答:3

我开始用C ++阅读mp3-文件。

一切顺利,直到我阅读了ID3-Tag的规格。 ID3v2-Header中有一些有关其大小的信息,存储在所谓的Synchsafe Integers中。这是一个四字节整数,其中每个字节的最高有效位设置为零。

我发现了如何将其转换为普通整数,但是我不停地问自己,为什么整数会以这种不必要的复杂方式存储。

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

integer mp3 id3 id3-tag
3个回答
24
投票

要了解为什么使用同步安全整数,对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写入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;
}

希望这会有所帮助。


3
投票

除了以上答案外,我想从我的博客中添加一个页面:http://phoxis.org/2010/05/08/synch-safe/


1
投票

6.2。同步安全整数

在标签的某些部分,使用不同步方案很不方便,因为未同步数据的大小是事先未知的,这在大小描述符中尤其成问题。 ID3v2中的解决方案是使用synchsafe整数,其中永远不会有任何错误的synch。同步安全整数是将其最高位(第7位)保持为零的整数,从而使八位中的七位可用。因此,一个32位的同步安全整数可以存储28位的信息。

来自http://www.id3.org/id3v2.4.0-structure

与给定文档中所谓的“非同步”紧密相关,您应该阅读整章的第六章。所有这些都与最大程度地与广泛的软件和硬件兼容。

© www.soinside.com 2019 - 2024. All rights reserved.