MP3 文件解析

如标题所示,但是仅实现了数据归类,包含解析文件头,文件尾,文件数据帧,数据帧头等内容,缺少解析vbr cbr数据的实现

需要先说明一下,MP3文件本身数据结构就是一堆帧构成,从上至下依次是

文件帧头,标签帧,填充空白帧,数据帧,文件信息帧

1.mp3文件头

这一段内容包含文件的各种信息,内容如下


// 文件头
typedef struct
{
    uint8_t header[3]; // 文件头
    uint8_t ver;       // 文件版本
    uint8_t revision;  // 子版本
    uint8_t flag;      // 标记
    uint8_t size[4];   // 大小
} mp3FileHeader_t;
2.mp3标签帧

这一段包含各种标签,用来展示这个曲子的多数内容,每个帧大小不同,包含的内容也不同,而且数量不定,或多或少,其中标签属性可以分解为下面的结构体内容,说明了一个标签的属性定义


// 标签头
typedef struct
{
    uint8_t header[4]; // 头
    uint8_t size[4];   // 标签大侠
    uint8_t flag[2];   // 标签属性
} mp3LableHeader_t;

// 标签头标志位的解析
typedef struct
{
    bool tagProtection;  // 标签保护
    bool fileProtection; // 文件保护
    bool readOnly;       // 只读
    bool compression;    // 压缩
    bool encrypt;        // 加密
    bool group;          // 属于某一组
} mp3LableHeaderFlag_t;
3.空白帧

无意义,跳过即可

4.数据帧的帧头

这块内容需要自己手动填充,需要对数据解析,包含了之后该怎么解析这个MP3的音频所需参数,包括

协议版本,协议层,是否CRC校验,位率,声道等

协议版本和协议层:这个决定了你要采取采样率,采样数,帧长度,这些东西有固定的计算方式和对应关系表,在计算时需要查表对照使用,如果你不想计算的话,可以采取其他博主的按字节查找FFFB这个,我个人觉得这很不靠谱.所以我没有采用

// 参考文档  https://blog.csdn.net/u010650845/article/details/53520426

typedef struct
{
    uint16_t syn;                       // 同步信息,所有位均为1
    uint8_t ver;                        // 版本,MPEG1
    uint8_t layer;                      // 层,Layer3
    uint8_t existCRC;                   // 无CRC校验
    uint16_t bitRate;                   // 位率,单位是kbps,320
    uint8_t samplingRate;               // 采样频率,44.1K
    uint8_t lengthAdjustment;           // 用来调整文件头长度,无需调整
    uint8_t reserve;                    // 保留字,未使用
    uint8_t soundChannel;               // 表示声道模式,立体声Stereo
    uint8_t stereo;                     // 声道模式为Joint Stereo时才使用
    uint8_t validityDetection;          // 文件是否合法,不合法
    uint8_t originalVersion;            // 是否原版,非原版
    uint8_t noiseReductionCompensation; // 用于声音经降噪压缩后再补偿的分类,未定义
} mp3DataHeader_t;
4.1.数据帧的通道信息

这一块没找到参考信息,故本文跳过

5. 代码实现
5.1 解析数据MP3文件头


    // 文件帧
    mp3FileHeader_t fileHeader = {0};
    fread(&fileHeader, 1, sizeof(mp3FileHeader_t), file);
    parseMp3FileHeader(fileHeader);

5.2 解析标签帧
  // 标签帧
        mp3LableHeader_t labheader = {0};
        fread(&labheader, 1, sizeof(mp3LableHeader_t), file);
        uint32_t labelLen = parseMp3LabelHeader(labheader);
5.3 解析数据帧
5.3.1 数据帧头
mp3DataHeader_t mp3DataHeader = {0};
        uint32_t frameLength = mp3DataHeaderParse(&mp3DataHeader, buf);
       
5.3.2 数据帧通道
mp3Sideinfo_t channelInfo = {0};
        // printf("channel info size %d\n", sizeof(mp3Sideinfo_t));
        // fread(&channelInfo, 1, sizeof(mp3Sideinfo_t), file);
        fread(&channelInfo, 1, 32, file);
        // mp3ChannelInfoParse(channelInfo);
5.3.3 数据帧内容-VBR帧头
mp3VBRHeader_t mp3VBRHeader = {0};
        fread(&mp3VBRHeader, 1, sizeof(mp3VBRHeader_t), file);
        printf(
            "mp3VBRHeader header [%#x]  fileFlag [%d] frameNumber [%d] fileLength [%d]\n",
            mp3VBRHeader.header,
            mp3VBRHeader.fileFlag,
            mp3VBRHeader.frameNumber,
            mp3VBRHeader.fileLength);
5.3.4 数据帧数据-VBR数据
frameLength = (frameLength - 32 - 4 - sizeof(mp3VBRHeader_t));
        printf("mp3 VBR OR CBR data addr index [%#x] data len [%d]\n", ftell(file), frameLength);
        uint8_t *rawData = (uint8_t *)malloc(frameLength);
        if (rawData == NULL)
        {
            isdataParam = false;
            printf("malloc fail!!\n");
            break;
        }
        memset(rawData, 0, frameLength);
        fread(rawData, 1, frameLength, file);

在此之后就需要对数据帧进行解析了,其中涉及到一些比较复杂的算法,暂未实现,数据内容是rawData

源代码查看 代码仓库icon-default.png?t=N7T8https://gitee.com/icandang/learn.git

项目下 test\mp3parse\mp3Parse.c 这个文件就是

6. 编译使用
编译-->  gcc .\mp3Parse.c -o .\mp3Parse
使用-->  .\mp3Parse.exe '.\余天易,徐梦圆 - 鹿鸣(Instrumental)Remix.mp3' > log.log
6. 最后效果显示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MP3文件是一种常见的音频文件格式,其结构是通过一系列的标记和数据块来实现的。下面我将详细介绍MP3文件的结构。 MP3文件首先包含一个文件,用于标识该文件是一个MP3文件文件通常由几个字节组成,其中包括一些标志位,如MPEG版本号、层号和位率等信息。这些信息帮助播放设备正确解析和处理该文件。 接下来是一些标记和数据块,通常称为帧。每个帧包含一个小的音频片段,由一些特定的格式和编码进行描述。这些帧按顺序排列,依次组成整个MP3文件。每个帧的长度可以不同,这取决于该帧所包含的音频片段的时长和复杂性。 每个帧的结构包括帧和帧数据两部分。帧包含一些标志位和元数据,如帧类型、比特率、采样率等信息。帧数据则是实际的音频流数据,经过特定压缩算法进行编码压缩。 值得注意的是,MP3文件还包含一些附加信息和元数据,如歌曲名称、艺术家、专辑封面等。这些信息通常存储在文件的尾部,被称为ID3标签。ID3标签可以提供更多的音乐信息,使得播放器可以显示相关信息。 总结起来,MP3文件的结构由文件、帧和附加信息组成。文件用于标识MP3文件和提供基本信息,帧则是音频数据的实际载体,而附加信息则为音乐文件提供更丰富的描述。通过解析这些结构,播放设备可以正确识别和播放MP3文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值