打印
[RISC-V MCU 创新应用比赛]

沁恒 CH32V103 解析mp3文件信息

[复制链接]
4588|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 gtbestom 于 2021-8-30 23:45 编辑

#申请原创#@21小跑堂
  在使用沁恒 CH32V103 单片机完成 mp3 播放器设计之前,首先要对 mp3 文件进行一些必要的解析
  虽然使用了 VS1003 硬解码 mp3 数据流,但仍然无法获取足够的信息
  先看从 VS1003 能获取到哪些信息






  简单点的 MP3 播放器,需要显示歌名,歌手名,总时长,播放进度,还有其他的一些信息

  这上面的信息剔除一些不常用的,可以获取到一些比较常用的信息,例如 MPEG 版本,Layer 层,采样率,比特率,声道,还有解码时间

  MPEG1.0,Layer3,就是我们平时常见的 MP3 类型了,根据这两个信息,再根据采样率索引和比特率索引,可以得到采样率和比特率





  那歌曲总时长,在哪里找呢?

  其实 MP3 文件并没有记录歌曲总时长,但是我们可以根据文件信息,大致估算歌曲时长:

  对于固定码率 MP3 文件(CBR):


  歌曲总时长(秒) = 文件大小(字节)÷ ( 比特率(Kbps)× 1000 ÷ 8 )





  例如 “佛系少女” 这首歌,按照这个方法计算,计算结果 195 秒(3分钟15秒),是正确的

  但是用文件大小计算,不总是正确的,文件大小 = 标签数据大小 + 音频数据大小,一种情况是文件标签太大,文件大小跟音频数据大小就相差太多,计算结果就会有比较大的偏差,另一种情况是可变码率 MP3 文件(VBR),计算结果也可能是错误的





  例如 “公子向北走” 这首歌,按照这个方法计算,计算结果 265 秒(4分钟25秒),而实际时长是 4 分钟 7 秒,头部标签占了 700 多K字节,如果不剔除这些标签信息,就无法得到准确的音频数据量和播放时长,还会导致另一个问题,进度条走了大约 10 秒,也没听到 VS1003 输出音频,因为单片机向 VS1003 传输的都是头部标签信息,没有音频数据

  头部信息为什么会这么大呢?看看资源管理器的预览,可以知道有些 MP3 是内置专辑图片的,这个图片一般也在头部信息里。





  MP3 头部,一般有 ID3v2 标签,在 MP3 尾部,还可能会有 ID3v1 标签和 APEv2 标签,这些标签有些描述了歌曲的:歌名、歌手名、专辑名、年份、专辑图片 等信息,如果能剔除这些标签,就能获取原始的音频数据流,先用 16进制 方式打开文件分析,可以看到 MP3 前3个字节为 “ID3”,说明该 MP3 包含 ID3v2 标签





  再看 MP3 文件末尾,可以看到 “TAG” 字符在文件末尾前 128字节处,说明包含 ID3v1 标签,如果 “TAG” 前32字节处还包含 “APETAGEX” 字符,说明也有 APEv2 标签





  只要计算好这些标签的总大小,就能比较准确的计算音频数据大小,事实上很多 MP3 文件都满足这一公式

  音频数据大小 = 文件大小 - ID3v2标签大小 - ID3v1标签大小 - APEv2标签大小

  再总结一下:

  文件头为“ID3”,说明有 ID3v2标签,不定长,读取第7-10字节数据,可以获得一个u32类型数据,加 10 就是 ID3v2 标签大小


ID3v2Size = 10 + (((buf[6]&0x7F)<<21) | ((buf[7]&0x7F)<<14) | ((buf[8]&0x7F)<<7) | (buf[9]&0x7F));

  文件尾倒数第128字节开始,有 “TAG”,说明有 ID3v1标签,恒定 128 字节长度
  文件尾倒数第32字节开始,或者 “TAG” 前32字节位置,有 “APETAGEX”,说明有 APEv2 标签,不定长,读取后面第13字节数据,可以获得一个u32类型数据,加 32 就是 ID3v2 标签大小

APEv2Size  = 32 + ( (buf[15] << 24) | (buf[14] << 16) | buf[13] << 8) | buf[12]);


  这里做了简要的计算,方便快速得到计算结果,详细的标签内容可以看相关文档,内容较多,这里就不展开

  至此就可以准确的计算  CBR 类型的 MP3 文件时长,不过我也遇到过极少情况 ID3v2 标签后不紧跟着音频数据的情况,需要查找音频同步信息头,找到第一帧音频,才能准确计算音频数据大小,音频同步头为2进制的 11111111 111xxxxx,即 11 位的 1 数据
  可变比特率 VBR 类型的 MP3 就无法这么计算了,因为比特率不是恒定的,这时候还是需要找到第一帧音频,分析 “XING”、“VBRI”、“INFO” 标签,来找到总帧数、帧数据总大小,再结合采样数、采样率来计算总时长。

  歌曲总时长(秒) = 总帧数 × 每帧采样数 ÷ 采样率;

  对于 MPEG1, Layer3 文件,即 MP3 文件而言,每帧采样数恒为 1152
  这种方法可以计算 VBR 类型 MP3 总时长,也可以计算 CBR 类型 MP3 总时长





  当然 ID3v1、ID3v2、APEv2 标签还包含有更多信息,可以用单片机进行解析,ID3v1 内容是 GBK 和 ASCII 编码的,可以简单的读取和显示到串口助手

  ID3v2 版本2版本3,文字多数是 Unicode UTF-16 编码的,需要 UTF-16 转 GBK 后,串口打印才不会乱码

  ID3v2 版本4,文字几乎都是 Unicode UTF-8 编码的,UTF-8 可以简单计算转换到 UTF-16,再转 GBK 打印到串口

  APEv2则规定了只用 Unicode UTF-8 编码文字

  UTF-16 转 GBK 需要较为复杂的对照表,之前一篇**我有进行了说明,有兴趣可以查看之前的帖子





使用特权

评论回复

相关帖子

沙发
qiufengsd| | 2022-11-5 11:05 | 只看该作者
这个解析mp3的时候,需要注意哪些

使用特权

评论回复
板凳
timfordlare| | 2022-11-5 11:19 | 只看该作者
这个语音模块如何通过iis进行数据的传输呢?

使用特权

评论回复
地板
ccook11| | 2022-11-5 11:37 | 只看该作者
可以实现远程wifi的语音播放和控制的吗?

使用特权

评论回复
5
kkzz| | 2022-11-5 12:07 | 只看该作者
wav和mp3在格式上有什么不同的吗?

使用特权

评论回复
6
小涛DZGZS| | 2022-11-7 01:12 | 只看该作者
大佬这款串口调试助手和hex编辑器叫什么,看起来好像挺不错的

使用特权

评论回复
7
豌豆爹| | 2022-11-7 15:58 | 只看该作者
根据楼主列举的这些歌可以菜单楼主是相当年轻啊,哈哈

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

98

帖子

0

粉丝