原文:https://blog.csdn.net/hongjiujing/article/details/2148370
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/io.h>
#define SEEK_END 2
void main()
{
FILE *fp=NULL;
int bHasID3V2=0;
char cVer=0;
char cRevision=0;
int bHasExtHeader=0;
int ID3V2_size=0;
#define ID3V1_size 128
char cID3V2_head[10]={0};
char cID3v2Frame_head[10]={0};
char *cID3v2Frame=NULL;
long iID3v2Frame_length=0;
/*##########################Symbol In Frame###################################*/
long iFrameStart=0,iFrameMove=0,iFrameCount=0;
unsigned long iFrameSize=0;
char cFrameHead_bin[33]={0};
char cFrameHead_bin_temp[9]={0};
/*##########################Symbol In ID3V1###################################*/
char cID3V1[128]={0};
/*##########################Symbol Above######################################*/
unsigned char* cBuffer=NULL;
int SamplingrateTable[3][3]={{44100,22050,11025},{48000,24000,120000},{32000,16000,8000}};
char* ChannelDescrip[4]={"立体声","混合立体声","双声","单声"};
int cBuffer_size=1024,Bitrate=0,FrameSize=0,FrameCount=0,mp3Duration=0;
char LayerDescript=0 ,bRateIndex=0 ,bSampleRate=0,Version=0,bPadding=0,bChannelMode=0;
long int flength=0;
int i=0,j=0;
char argv[]={"music.mp3"};
/*##########################Symbol Above######################################*/
void getBin(int ,char* );
int GetBitRate(int ,int , int ); //函数宣告
if((fp=fopen(argv,"rb"))==NULL)
{
printf("<%s, %d>ERROR:can't open the file!\n", __FILE__, __LINE__);
getchar();
exit(1);
}
/*##########################ID3V2 Reading#####################################*/
fread(cID3V2_head,10,1,fp);
if( (cID3V2_head[0]=='I'||cID3V2_head[1]=='i')
&&(cID3V2_head[1]=='D'||cID3V2_head[2]=='d')
&&cID3V2_head[2]=='3')
{
bHasID3V2=1;
cVer=cID3V2_head[3];
cRevision=cID3V2_head[4];
if(cID3V2_head[5]&0x64==0x64) bHasExtHeader = 1;
if(cID3V2_head[5]&0x10==0x10) bHasExtHeader = 1;
//ID3V2_size = (cID3V2_head[6]&0x7F)*0x200000
//+ (cID3V2_head[7]&0x7F)*0x400
//+ (cID3V2_head[8]&0x7F)*0x80
//+ (cID3V2_head[9]&0x7F);
ID3V2_size= (cID3V2_head[6]&0x7F) << 21
| (cID3V2_head[7]&0x7F) << 14
| (cID3V2_head[8]&0x7F) << 7
| (cID3V2_head[9]&0x7F) + 10 ;
printf("<%s, %d>ID3V2_size:%d bytes\n",__FILE__, __LINE__, ID3V2_size);
iFrameStart=--ID3V2_size;
}
else
{
bHasID3V2=0;
printf("<%s, %d>There is no ID3V2*\n", __FILE__, __LINE__);
}
rewind(fp); /*改文件指针指向文件头*/
fseek(fp,10L,1);
while((ftell(fp)+10)<=ID3V2_size)
{
memset(cID3v2Frame_head,0,10); /*内存清空*/
fread(cID3v2Frame_head,10,1,fp); /*ID3V2帧信息头读取*/
iID3v2Frame_length =(long)(cID3v2Frame_head[4]*0x100000000
+cID3v2Frame_head[5]*0x10000
+cID3v2Frame_head[6]*0x100
+cID3v2Frame_head[7]); /*计算帧的大小.*/
if (cID3v2Frame_head[0]=='/0'
&& cID3v2Frame_head[1]=='/0'
&& cID3v2Frame_head[2]=='/0'
&& cID3v2Frame_head[3]=='/0')
break;
#if 0
for (i=0;i<4;i++) putchar(cID3v2Frame_head[i]); /*FrameSign(4)*/
putchar('-');putchar('>'); /* Print "->"*/
cID3v2Frame=malloc(iID3v2Frame_length); /* 为 cID3v2Frame 指针分配内存, 功能类似于VB中的动态数组*/
if (cID3v2Frame!=NULL) // 检测动态内存分配是否已经成功
{
fread(cID3v2Frame,iID3v2Frame_length,1,fp);
i=0;
while(i<iID3v2Frame_length)
{
putchar(cID3v2Frame[i]);
i++;
}
putchar('/n');
free(cID3v2Frame);
}
else
{
if(fp!=NULL) fclose(fp);
printf("<%s, %d>ERROR:Memory Exhausted!\n", __FILE__, __LINE__);
exit(1);
}
#endif
}
putchar('*');
putchar('\n');
/*(mp3_FrameHeader) Reading*/
fseek(fp, 0L, SEEK_END); //移文件指针到文件尾
flength = ftell(fp); //文件长
rewind(fp);
fseek(fp,10+ID3V2_size,1);
while((ftell(fp)+4)<flength)
{
if (ftell(fp)+1024<=flength)
cBuffer_size=1024;
else
cBuffer_size=flength-ftell(fp);
cBuffer=malloc(cBuffer_size);
if (cBuffer==NULL) // 检测动态内存分配是否已经成功
{
if (fp!=NULL) fclose(fp);
printf("<%s, %d>ERROR:Memory Exhausted!\n", __FILE__, __LINE__);
exit(1);
}
memset(cBuffer,0,cBuffer_size);
fread(cBuffer,cBuffer_size,1,fp);
for(i=0;i<(cBuffer_size-4); i++)
{
//Mp3帧头(FRAMEHEADER)格式如下:AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
LayerDescript = (cBuffer[i+1] & 0x6)>>1; //Part CC IN 'AAABBCCD' ,Layer description '00' - reserved
//Part EEEE in 'EEEEFFGH', But '1111' is Bad Bitrate index, "bad" means that this is not an allowed value
bRateIndex = cBuffer[i+2] /0x10 ; // EEEEXXXX!='1111'
bSampleRate = (cBuffer[i+2] & 0xA) >>2 ; //Part FF IN 'EEEEFFGH' ,'11' reserved
if (cBuffer[i] ==0xFF
&& cBuffer[i+1] > 0xE0
&& bRateIndex != 0xF
&& LayerDescript != 0x0
&& bSampleRate < 0x3 )
{
printf("<%s, %d>Mp3_FrameHeader->\n", __FILE__, __LINE__);
memset(cFrameHead_bin,0,32);
j=cBuffer[i];
getBin(j,cFrameHead_bin_temp);
strcat(cFrameHead_bin,cFrameHead_bin_temp);
putchar('-');
j=cBuffer[i+1];
getBin(j,cFrameHead_bin_temp);
strcat(cFrameHead_bin,cFrameHead_bin_temp);//strcat的两个传入参数都必需以 '/0' 代表结尾
putchar('-');
j=cBuffer[i+2];
getBin(j,cFrameHead_bin_temp);
strcat(cFrameHead_bin,cFrameHead_bin_temp);
putchar('-');
j=cBuffer[i+3];
getBin(j,cFrameHead_bin_temp);
strcat(cFrameHead_bin,cFrameHead_bin_temp);
Version = (cBuffer[i+1] & 0x18)>>3;
bPadding=(cBuffer[i+1] & 0x2)>>1;
Bitrate = GetBitRate(bRateIndex, LayerDescript, Version);
bChannelMode=(cBuffer[i+3] & 0xC0)>>6;
putchar ('\n');
if (bRateIndex != 0)
{
switch (Version)
{
case 0:
printf("<%s, %d>MPEG 2.5 层 %d, %dHz %s\n",__FILE__, __LINE__, 4-LayerDescript,
SamplingrateTable[bSampleRate][2],ChannelDescrip[bChannelMode]);
FrameSize = ((72 * Bitrate*1000) / SamplingrateTable[bSampleRate][2]) +
bPadding;
FrameCount=(int)((flength-(ftell(fp)-cBuffer_size+i)) /FrameSize);
mp3Duration=(int)(FrameCount*0.026); //每帧的播放时间:无论帧长是多少,每帧的播放时间都是26ms;
printf("<%s, %d>CBR:-> %dKbit %d帧\n",__FILE__, __LINE__, Bitrate,FrameCount);
printf("<%s, %d>长度:%d 秒\n", __FILE__, __LINE__, mp3Duration);
break;
case 2:
printf("<%s, %d>MPEG 2.0 层 %d, %dHz %s\n", __FILE__, __LINE__, 4-LayerDescript,
SamplingrateTable[bSampleRate][1],ChannelDescrip[bChannelMode]);
FrameSize = ((72 * Bitrate*1000) / SamplingrateTable[bSampleRate][1]) +
bPadding;
FrameCount=(int)((flength-(ftell(fp)-cBuffer_size+i)) /FrameSize);
mp3Duration=(int)(FrameCount*0.026); //每帧的播放时间:无论帧长是多少,每帧的播放时间都是26ms;
printf("<%s, %d>CBR:-> %dKbit %d帧\n", __FILE__, __LINE__, Bitrate,FrameCount);
printf("<%s, %d>长度:%d 秒\n", __FILE__, __LINE__, mp3Duration);
break;
case 3:
printf("<%s, %d>MPEG 1.0 层 %d, %dHz %s\n", __FILE__, __LINE__, 4-LayerDescript,
SamplingrateTable[bSampleRate][0],ChannelDescrip[bChannelMode]);
FrameSize = ((144 * Bitrate*1000) / SamplingrateTable[bSampleRate][0]) +
bPadding;
FrameCount=(int)((flength-(ftell(fp)-cBuffer_size+i)) /FrameSize);
mp3Duration=(int)(FrameCount*0.026); //每帧的播放时间:无论帧长是多少,每帧的播放时间都是26ms;
printf("<%s, %d>CBR:->%dKbit %dFrame\n", __FILE__, __LINE__, Bitrate,FrameCount);
printf("<%s, %d>mp3Duration:%ds\n", __FILE__, __LINE__, mp3Duration);
break;
}
}
else
printf("<%s, %d>This a Free Rate MP3 File!\n", __FILE__, __LINE__);
cBuffer_size=-1;
break;
}
}
free(cBuffer);
if (cBuffer_size ==(-1) ) break;
}
/*ID3V1 Reading*/
fseek(fp,-128L,SEEK_END);
fread(cID3V1,ID3V1_size ,1,fp);
if((cID3V1[0]=='T'||cID3V1[0]=='t')
&&(cID3V1[1]=='A'||cID3V1[1]=='a')
&&(cID3V1[2]=='G'||cID3V1[2]=='g'))
{
printf("<%s, %d>ID3V1_size:%d bytes\n", __FILE__, __LINE__, ID3V1_size );
for(i=0;i<128;i++) putchar(cID3V1[i]);
putchar('\n');
}
else
{
printf("<%s, %d>There is no ID3V1\n", __FILE__, __LINE__);
}
fclose(fp);
}
void getBin( int dec,char* bin)
{
#if 0
int i,j,len;
char temp[8];
memset(temp,0,8);
itoa(dec,temp,2); ///把整数i转换成字符串将i转换为字符串放入temp中,最后一个数字表示2进制
len=strlen(temp);
memset(bin,0,strlen(bin));
for(i=0,j=0;i<8;i++,j++)
{
if (temp[j]!='/0')
bin[i]=temp[j];
else
bin[i]='0';
}
bin[i]='/0';
for(i=0,j=0;i<8;i++,j++) putchar(bin[i]);
#endif
}
int GetBitRate(int bRateIndex,int LayerDescript, int Version)
{
int BitrateTable[6][15]=
{
{-1,32,64,96,128,160,192,224,256,288,320,352,384,416,448},
{-1,32,48,56,64,80,96,112,128,160,192,224,256,320,384},
{-1,32,40,48,56,64,80,96,112,128,160,192,224,256,320},
{-1,32,64,96,128,160,192,2324,256,288,320,352,384,416,448},
{-1,32,48,56,64,80,96,112,128,160,192,224,256,320,384},
{-1,8,16,24,32,64,80,56,64,128,160,112,128,256,320}
}; //kbps (-1) means :free
int i,j;
if (Version==3 && LayerDescript==3 )j=0;
else if (Version==3 && LayerDescript==2 )j=1;
else if (Version==3 && LayerDescript==1 )j=2;
else if (Version==2 && LayerDescript==1 )j=3;
else if (Version==2 && LayerDescript==2 )j=4;
else if (Version==2 && LayerDescript==3 )j=5;
i=BitrateTable[j][bRateIndex];
return i;
}