我是靠谱客的博主 贪玩流沙,最近开发中收集的这篇文章主要介绍MP3文件头部信息解码- ID3V1,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

ID3V1

mp3解码的课题断断续续做了一年多了,这是我学习c语言之后想自己写的第一个课题,如果时光倒退,冒出这个想法的第一时间,我会给自己一个嘴巴子,搞搞贪吃蛇、五子棋什么的不好,非要搞mp3解码,为了这个,这一年我都忘记自己看了多少论文了。

各种论坛上有巨量的关于这个课题的文章,其中大量的都是头部信息的,盖上个文件解码的标题,白白浪费了宝宝很多时间。凭借着一股傻乎劲,宝宝从一无所知,逐渐也揭开了mp3的面纱,但是有些细节还是没摸透。并且,宝宝成功的卡在了哈夫曼码区。

宝宝心里苦呀,凭我的智商又不能完全搞得了整个MP3的解码,不搞完它,心理又始终惦记着,不从这个坑里走出来,宝宝人大概就废了,于是宝宝含着眼泪继续再一次卷土重来,这一次一定要把这个课题给结了。

文件结构

MP3文件的结构是这个样子的:

头部音频数据尾部
ID3V2DATAID3V1
可以不存在必须的可以不存在

这是mp3文件宏观的样子,最主要的是音频数据,但宝宝现在还动不了它,所以关于它的各种例如心理学模型,哈夫曼编解码,傅里叶变换之类的,统统先不搞,下一个阶段再收拾它。

宝宝现在就盯准头部和尾部,就是传说的ID3V1和V2。
传统的mp3要么是 头部+音频数据 要么是 音频数据+尾部
但是自从ID3V2.4之后,就变成可以这个样子:头部 + 音频数据 + 尾部

ID3

这货大约是一种在mp3文件中附加例如歌手等信息的一种标准,它不是mp3的必要部分,mp3解码也用不上它,实际上mp3文件可以仅仅只有 音频数据
ID3v1可以在音频数据后面附加128字节的信息,为了在文件中附加更多的信息,于是有了ID3V2,它的升级版,为了不破坏ID3V1的读写,它放到了头部,并且采用了变长的方式。以下是它的版本

ID3V1流行度
逐渐少见了
ID3V2流行度
2.1几乎没
2.2几乎没
2.3主流
2.4很少

从其他大佬的文章中可以看到ID3V2有四个版本,但是从我保存的mp3文件中,并没有找到2.1和2.2的,暂时也没有找到跟这两个版本相关的资料。
官方传送门
ID3V2.3
ID3V2.4

ID3V1

ID3V1的结构非常简单,只有128字节

offsetlenvalue说明
0x03TAG段标识
0x330歌名
0x2130作者
0x3f30专辑名
0x5d4年份
0x6128附注
0x7d1保留位(说明音轨有无)
0x7e1音轨号
0x7f1mp3类型

另:有资料说保留位和音轨号的两个byte属于附注,咱也不懂,咱也不敢问。
ps:看到有资料说,id3v1 有两个版本,一个是v1,一个是v1.1,1.1版本就是从附注中划出了音轨部分的两个字节

数据结构:

typedef struct id3v1
{
char	Tag[3];
char	Title[30];
char	Artist[30];
char	Album[30];
char	Year[4];
char	Comment[28];
unsigned char	Reserved;
unsigned char	TrackNum;
unsigned char	GenreIndex;
}ID3V1;

ID3V1略烦人的地方就是GenreIndex,它定义了140多种音乐类型,据说原来有差不多100种,然后Winamp扩充到125种,算上其他的,总共有140多种,要想知道这个值里的对应啥类型,还得建个表

#define GENRE_INDEX_MAX
148
char *Genre[GENRE_INDEX_MAX]=
{
"Blues","ClassicRock","Country","Dance","Disco","Funk","Grunge","Hip-Hop",
"Jazz","Metal","NewAge","Oldies","Other","Pop","R&B","Rap",
"Reggae","Rock","Techno","Industrial","Alternative","Ska","Deathl","Pranks",
"Soundtrack","Euro-Techno","Ambient","Trip-Hop","Vocal","Jazz+Funk","Fusion","Trance",
"Classical","Instrumental","Acid","House","Game","SoundClip","Gospel","Noise",
"AlternRock","Bass","Soul","Punk","Space","Meditative","InstrumentalPop","InstrumentalRock",
"Ethnic","Gothic","Darkwave","Techno-Industrial","Electronic","Pop-Folk","Eurodance","Dream",
"SouthernRock","Comedy","Cult","Gangsta","Top40","ChristianRap","Pop/Funk","Jungle",
"NativeAmerican","Cabaret","NewWave","Psychadelic","Rave","Showtunes","Trailer","Lo-Fi",
"Tribal","AcidPunk","AcidJazz","Polka","Retro","Musical","Rock&Roll","HardRock",
//Winamp扩充
"Folk","Folk-Rock","NationalFolk","Swing","FastFusion","Bebob","Latin","Revival",
"Celtic","Bluegrass","Avantgarde","GothicRock","ProgessiveRock","PsychedelicRock","SymphonicRock","SlowRock",
"BigBand","Chorus","EasyListening","Acoustic","Humour","Speech","Chanson","Opera",
"ChamberMusic","Sonata","Symphony","BootyBass","Primus","PornGroove","Satire","SlowJam",
"Club","Tango","Samba","Folklore","Ballad","PowerBallad","RhythmicSoul","Freestyle",
"Duet","PunkRock","DrumSolo","Acapella","Euro-House","DanceHall",
//其他扩充
"Goa","Drum&Bass","Club-House","Hardcore","Terror","Indie","BritPop","Negerpunk",
"PolskPunk","Beat","ChristianGangstaRap","Heavyl","Blackl","Crossover","ContemporaryChristian","ChristianRock",
"Merengue","Salsa","Trashl","Anime","JPop","Synthpop"
};

完整的测试

#include <stdio.h>
#define GENRE_INDEX_MAX
148
typedef struct id3v1
{
char	Tag[3];
char	Title[30];
char	Artist[30];
char	Album[30];
char	Year[4];
char	Comment[28];
unsigned char	Reserved;
unsigned char	TrackNum;
unsigned char	GenreIndex;
}ID3V1;
char *Genre[GENRE_INDEX_MAX]=
{
"Blues","ClassicRock","Country","Dance","Disco","Funk","Grunge","Hip-Hop",
"Jazz","Metal","NewAge","Oldies","Other","Pop","R&B","Rap",
"Reggae","Rock","Techno","Industrial","Alternative","Ska","Deathl","Pranks",
"Soundtrack","Euro-Techno","Ambient","Trip-Hop","Vocal","Jazz+Funk","Fusion","Trance",
"Classical","Instrumental","Acid","House","Game","SoundClip","Gospel","Noise",
"AlternRock","Bass","Soul","Punk","Space","Meditative","InstrumentalPop","InstrumentalRock",
"Ethnic","Gothic","Darkwave","Techno-Industrial","Electronic","Pop-Folk","Eurodance","Dream",
"SouthernRock","Comedy","Cult","Gangsta","Top40","ChristianRap","Pop/Funk","Jungle",
"NativeAmerican","Cabaret","NewWave","Psychadelic","Rave","Showtunes","Trailer","Lo-Fi",
"Tribal","AcidPunk","AcidJazz","Polka","Retro","Musical","Rock&Roll","HardRock",
//Winamp扩充
"Folk","Folk-Rock","NationalFolk","Swing","FastFusion","Bebob","Latin","Revival",
"Celtic","Bluegrass","Avantgarde","GothicRock","ProgessiveRock","PsychedelicRock","SymphonicRock","SlowRock",
"BigBand","Chorus","EasyListening","Acoustic","Humour","Speech","Chanson","Opera",
"ChamberMusic","Sonata","Symphony","BootyBass","Primus","PornGroove","Satire","SlowJam",
"Club","Tango","Samba","Folklore","Ballad","PowerBallad","RhythmicSoul","Freestyle",
"Duet","PunkRock","DrumSolo","Acapella","Euro-House","DanceHall",
//其他扩充
"Goa","Drum&Bass","Club-House","Hardcore","Terror","Indie","BritPop","Negerpunk",
"PolskPunk","Beat","ChristianGangstaRap","Heavyl","Blackl","Crossover","ContemporaryChristian","ChristianRock",
"Merengue","Salsa","Trashl","Anime","JPop","Synthpop"
};
int main()
{
ID3V1 id3;
FILE *fp;
fp = fopen("ID3V1.mp3","rb");
if(fp == NULL)return -1;
fseek(fp,-128,SEEK_END);
fread((void*)&id3,1,128,fp);
printf("----------------ID3V1Info----------------n");
if(strcmp(id3.Tag,"TAG") != 0)
{
printf("not exist ID3V1");
return -1;
}
else
{
printf("Tag:tt%.3sn",id3.Tag);
printf("Title:tt%.30sn",id3.Title);
printf("Artist:tt%.30sn",id3.Artist);
printf("Album:tt%.30sn",id3.Album);
printf("Year:tt%.4sn",id3.Year);
printf("Comment:t%.28sn",id3.Comment);
printf("Reserved:t%xn",id3.Reserved);
printf("TrackNum:t%xn",id3.TrackNum);
printf("Genre:tt%sn",id3.GenreIndex < GENRE_INDEX_MAX ? Genre[id3.GenreIndex]:"null");
}
printf("----------------------------------------nn");
fclose(fp);
return 0;
}

关于ID3更多的信息

最后

以上就是贪玩流沙为你收集整理的MP3文件头部信息解码- ID3V1的全部内容,希望文章能够帮你解决MP3文件头部信息解码- ID3V1所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(34)

评论列表共有 0 条评论

立即
投稿
返回
顶部