
每个ID3V2.3的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在MP3文件的首部。
标签头
在文件的首部顺序记录10个字节的ID3V2.3的头部。数据结构如下:
char Header[3]; /*必须为"ID3"否则认为标签不存在*/
char Ver; /*版本号;ID3V2.3就记录03,ID3V2.4就记录04*/
char Revision; /*副版本号;此版本记录为00*/
char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/
char Size[4]; /*标签大小,包括标签帧和扩展标签头。(不包括标签头的10个字节)*/
1.标志字节
标志字节一般为0,定义如下:
abc00000
a -- 表示是否使用不同步(一般不设置)
b -- 表示是否有扩展头部,一般没有(至少Winamp没有记录),所以一般也不设置
c -- 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置)
2.标签大小
一共四个字节,但每个字节只用7位,最高位不使用恒为0。所以格式如下
0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx
计算大小时要将0去掉,得到一个28位的二进制数,就是标签大小(不懂为什么要这样做),计算公式如下:
int total_size;
total_size = Size[0]*0x200000
+Size[1]*0x4000
+Size[2]*0x80
+Size[3]
标签帧
每个标签帧都有一个10个字节的帧头和至少一个字节的不固定长度的内容组成。它们也是顺序存放在文件中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中得到内容大小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。
帧头的定义如下:
char FrameID[4]; /*用四个字符标识一个帧,说明其内容,稍后有常用的标识对照表*/
char Size[4]; /*帧内容的大小,不包括帧头,不得小于1*/
char Flags[2]; /*存放标志,只定义了6位,稍后详细解说*/
1.帧标识
用四个字符标识一个帧,说明一个帧的内容含义,常用的对照如下:
TIT2=标题 表示内容为这首歌的标题,下同
TPE1=作者
TALB=专集
TRCK=音轨 格式:N/M 其中N为专集中的第N首,M为专集中共M首,N和M为ASCII码表示的数字
TYER=年代 是用ASCII码表示的数字
TCON=类型 直接用字符串表示
COMM=备注 格式:"eng\0备注内容",其中eng表示备注所使用的自然语言
2.大小
这个可没有标签头的算法那么麻烦,每个字节的8位全用,格式如下
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
算法如下:
int FSize;
FSize = Size[0]*0x1000000
+Size[1]*0x10000
+Size[2]*0x100
+Size[3];
用以上信息可以获取MP3歌曲文件的一些基本信息了!

分享一下BMP文件的格式和怎么去读取它和显示
void DisplayBMP(uint16 x,uint16 y,uint8 *pBMP)
{
uint32 SizeBmp = 0;
// ClearScreen(Magenta);
FAT32_Open_File(&OpenFileInfo,pBMP,0);
FAT32_Read_File(&OpenFileInfo,0,54,gTableBmp);
if((gTableBmp[0] == 'B') && (gTableBmp[1] == 'M'))
{
gBmpOffSet = gTableBmp[13];
gBmpOffSet <<= 8;
gBmpOffSet |= gTableBmp[12];
gBmpOffSet <<= 8;
gBmpOffSet |= gTableBmp[11];
gBmpOffSet <<= 8;
gBmpOffSet |= gTableBmp[10];
gBmpW = gTableBmp[21];
gBmpW <<= 8;
gBmpW |= gTableBmp[20];
gBmpW <<= 8;
gBmpW |= gTableBmp[19];
gBmpW <<= 8;
gBmpW |= gTableBmp[18];
gBmpH = gTableBmp[25];
gBmpH <<= 8;
gBmpH |= gTableBmp[24];
gBmpH <<= 8;
gBmpH |= gTableBmp[23];
gBmpH <<= 8;
gBmpH |= gTableBmp[22];
gBmpBit = gTableBmp[28];
SizeBmp = gBmpH * gBmpW * gBmpBit;
ClearPartScreen(x,x + gBmpW - 1,y,y + gBmpH - 1,Magenta);
//TFTSetPos(x,x + gBmpW - 1,y,y + gBmpH - 1);
gbmpx = x;
gbmpy = y;
FAT32_Read_FileX(&OpenFileInfo,gBmpOffSet,SizeBmp,DrawBmp);
}
else
{
TFTDisplayHzString(100,163,"不是BMP文件...",Red,Magenta);
}
}


彩屏一般不带字库的,在刚开始的时候我也无法去在上面大量显示汉字,取模太多装不下。导致开始的歌曲选择也只能靠图片来选择歌曲,也无法显示出每首歌对于的歌曲名和歌手名。在之后我在网上找到了些资料,是关于制作彩屏字库的,然后开始搞这个字库的问题。在网上找到了一个字库的.bin文件,我将它放在SD卡里面,来读取字库里面的数据显示对应的汉字,这就有了一个很糟糕的问题,那就是速度慢了,显示汉字时间太长,所以显示一些信息还可以,但是如果要刷新歌词什么的,我感觉很困难,这几天也试过很多方法但是也没有好的办法来提高这个速度。真的很纠结了......

在做DIYMP3的整个过程中遇到了一些问题,慢慢的,只要自己琢磨还是会解决的。一个DIYMP3的制作,刚开始就需要写一个简单的菜单,我感觉菜单界面是一个有人机界面作品必须要的。我是用结构体来写的菜单,我觉得挺好用的,所以这里分享给大家,主要代码如下:
typedef struct
{
uint8 KeyStateIndex; //当前的状态索引号
uint8 KeyDownState; //按下向下的按键后的索引号
uint8 KeyUpState; //按下向上的索引号
uint8 KeySureState; //按下确定
uint8 KeyBackState; //按下返回
void (*CurrentOperate)(); //当前状态需要执行的函数
}MenuTab;
一个结构体可以解决菜单的很多问题了。
在就是SD卡是必须要搞的,文件级操作是这个的基础了。我借鉴的是振南的FAT,经过很多网友使用,znFAT已经相当的完整了,可以完成一些项目和作品。znfat操作也很简单,只需要提供扇区读写函数给FAT调用就好了,其他的就是定义所使用外部存储器的类型,SD卡还是U盘等,上面的东西设定好了之后再声明一个结构体,
struct FAT32_Init_Arg *pArg;
struct FAT32_Init_Arg FAT_Init_SD;
struct FileInfoStruct OpenFileInfo;
unsigned char Dev_No;
pArg = &FAT_Init_SD;
Dev_No = SDCARD;
之后就是VS1003,其实VS1003基本操作很简单,就是读写寄存器,我想分享的是频谱,在读频谱的是要给VS1003写入一段代码,之后就可以读取频谱了,14个频段。具体代码太长这里就不贴上来了,在沁恒的网站上有相应的资料。
彩屏是一个很纠结的问题,就是没有字库,刚开始我也没多考虑这个,只是觉得取模就好了。但是最后要大量显示文字和读取歌曲信息的时候就很要命了,这个取模简直弱爆了。最后在网上查了开始琢磨着字库,经过在网上各大论坛逛了几天找到了一个字库文件.bin文件。我开始尝试把这个文件放在SD卡里面,然后读取里面的数据显示。尝试了半天感觉可以,但是速度感觉很慢,这个就直接否定我要显示歌词,速度慢跟不上。字库一般论坛上很多,大家可以自己找找哦!按照我的用法用就好了。
刚开始没显示一张图片都要用软件去取模,太麻烦了,开始解码BMP文件,这种格式的图片编码有一定规律,可以通过单片机解码然后去显示,实现了,现在方便多了,对于BMP文件的编码格式,可以浏览http://baike.baidu.com/view/7671.htm
最后一个问题就是对于MP3文件编码的分析了,对于MP3编码我更喜欢的是ID3V2,这个编码对于单片机去分析有很大好处,它的信息都在文件的开头,读出来的时间花的少,ID3V1信息都在文件最后的128个字节,如果去读取花的时间要长很多。这里分享一个链接http://baike.baidu.com/view/66078.htm
这次我学到了很多,,,感谢这次活动了,瑞萨单片机IO功能太多,用起来得好好把握!!!学习东西还是要在做一个具体的实物中来探索和发现。

回复
有奖活动 | |
---|---|
【EEPW电子工程师创研计划】技术变现通道已开启~ | |
发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
【EEPW在线】E起听工程师的声音! | |
“我踩过的那些坑”主题活动——第001期 | |
高校联络员开始招募啦!有惊喜!! | |
【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
送您一块开发板,2025年“我要开发板活动”又开始了! | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【我踩过的那些坑】STM32的硬件通讯调试过程的“坑”被打赏50分 | |
【我踩过的那些坑】晶振使用的问题被打赏100分 | |
【我踩过的那些坑】电感选型错误导致的处理器连接不上被打赏50分 | |
【我踩过的那些坑】工作那些年踩过的记忆深刻的坑被打赏10分 | |
【我踩过的那些坑】DRC使用位置错误导致的问题被打赏100分 | |
我踩过的那些坑之混合OTL功放与落地音箱被打赏50分 | |
汽车电子中巡航控制系统的使用被打赏10分 | |
【我踩过的那些坑】工作那些年踩过的记忆深刻的坑被打赏100分 | |
分享汽车电子中巡航控制系统知识被打赏10分 | |
分享安全气囊系统的检修注意事项被打赏10分 |