-1

我正在尝试解析 MP3 文件并检测可变比特率 (VBR) MP3 文件中的所有帧。我浏览了整个互联网,找不到合适的解决方案来检测新的帧头同步。从其他帖子中它说我应该寻找 FFE 或 FFF 但在我的程序中它不会正确检测到它。我不明白我应该如何寻找 FFF 或 FFE ?我将 FFE 作为 0xF 并将下一个字节作为 0xFE 但是如何获得 FFF 我从中获取标头以构建所需的 11 位?我已经查看了在所有其他主题和网站中链接的这个作为 MP3 参考的去处,以及它的源代码,但涵盖我的问题的部分是,我假设在源代码中没有给出的 CMPA* 文件中代码下载。

do 
    {
        uiFrame = getc(pFile);
        if(EOF == uiFrame)
            break;
        cntSize++;
        if(0xFF == uiFrame)
        {
            uiFrame = getc(pFile);
            if(EOF == uiFrame)
                break;
            if((0xE == uiFrame) )//|| (0xE0 == uiFrame))
            {
                if(1 != uiFrameCount)
                    printf("\nFrame Size is %d \n\n",cntSize - PrevoiusFrameSize);

                printf("\nFrame Found at Byte %d", cntSize);
                PrevoiusFrameSize = cntSize;
                CheckFlag         = 1;
                uiFrameCount++;
            }
            cntSize++;
        }
    }while(1 != CheckFlag);

当我执行上面的代码或其任何我能想到的变体时,我会获得 1 到 6 帧,而如果我从上面的链接中使用程序本身,它会在我的测试 mp3 文件上显示 8855 帧。非常感谢您对此事的任何帮助,因为我已经没有想法和谷歌页面来寻找答案了。

谢谢您的帮助。

编辑:在 Marc BI 的快速回复后,大部分人都理解了这个问题,但在编辑以反映他的回答后,我现在只检测到 4 帧,从 1 帧开始。这是进行帧检测的代码部分,我做错了吗?

do 
    {
        uiFrame = getc(pFile);
        if(EOF == uiFrame)
            break;
        cntSize++;
        if(0xFF == uiFrame)
        {
            uiFrame = getc(pFile);
            if(EOF == uiFrame)
                break;
            uiShift=uiFrame>>4;
            if((0xE == uiShift) || (0xF == uiShift))
            {
                if(1 != uiFrameCount)
                    printf("\nFrame Size is %d \n\n",cntSize - PrevoiusFrameSize);

                printf("\nFrame Found at Byte %d", cntSize);
                PrevoiusFrameSize = cntSize;
                CheckFlag         = 1;
                uiFrameCount++;
            }
            cntSize++;
        }
    }while(1 != CheckFlag);
4

3 回答 3

1

标头的 3 个半字节(又名 1.5 个字节),所以你需要做一些位移。在伪代码中:

$data = 'FFEABCDEF....'
         ^^^--3 nibble header
$nibble1 = $data[0];
$nibble2 = $data[1] >> 4; // isolate 3rd nibble
if ($nibble1 == 'FF') && (($nibble2 == 'F') || ($nibble2 == 'E')) { ... }
于 2013-06-22T20:53:46.483 回答
0

您可以使用以下 C 宏轻松反转(4 字节)帧头中的字节顺序:

#define swaplong(x)  (unsigned  long)((((x)>>24) & 0xFF) |
((((x) & 0xFF0000) >> 8) & 0xFF00) | (((x) & 0xFF00) << 8) | ((x) << 24))

然后同步位(再次)相邻并且分析更直接。

于 2014-04-14T14:16:40.150 回答
0

您需要逐帧进行。每个帧都以您需要“解码”的 32 位标头开始。检查以下文件

完成后,您将获得下一个 [header+frame] 块的偏移量。

享受 :)

于 2013-11-17T16:05:13.213 回答