📄 id3v2.cpp
字号:
/***************************************** Copyright (c) 2001-2002 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the Jasper DVD player *//** @file id3v2.cpp @brief ID3 tag library <long description> @author TKG @date 2002-06*/#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include "caribbean_plainc.h" #include "id3v2.h"#if 0#define ID3DBG ENABLE#else#define ID3DBG DISABLE#endifint ParseID3v1Tags(const char *filename, ID3FileInf *FileData){ char tag[128]; int fd; int nb; fd=open(filename, O_RDONLY); if(fd==-1) { perror("ParseID3v1Tags: Cant open mp3 file"); return -1; } FileData->FileSize=lseek(fd, -128, SEEK_END)+128; nb=read(fd, tag, 128); close(fd); if(nb!=128) { RMDBGLOG((ID3DBG,"read = %d\n",nb)); perror("ParseID3v1Tags: Unable to read 128 bytes"); return -1; } if(!memcmp(tag,"TAG",3)) { FileData->HasID3v1Tag = TRUE; RMDBGLOG((ID3DBG,"ID3v1 Tag found\n")); //Found ID3v1.1 tag memcpy(FileData->v1SongTitle, tag+3, 30); FileData->v1SongTitle[30]=0; RMDBGLOG((ID3DBG,"Song Title %s\n", FileData->v1SongTitle)); memcpy(FileData->v1Artist, tag+33, 30); FileData->v1Artist[30]=0; RMDBGLOG((ID3DBG,"Artist %s\n", FileData->v1Artist)); memcpy(FileData->v1Album, tag+63, 30); FileData->v1Album[30]=0; RMDBGLOG((ID3DBG,"Album %s\n", FileData->v1Album)); memcpy(FileData->v1Year, tag+93, 4); FileData->v1Year[4]=0; RMDBGLOG((ID3DBG,"Year %s\n", FileData->v1Year)); memcpy(FileData->v1Comment, tag+97, 30); FileData->v1Comment[30]=0; RMDBGLOG((ID3DBG,"Comment %s\n", FileData->v1Comment)); FileData->v1Track = tag[126]; if(FileData->v1Track!=0) RMDBGLOG((ID3DBG,"Track %d\n", FileData->v1Track-'0')); FileData->v1Genre = tag[127]; RMDBGLOG((ID3DBG,"Genre %d\n", FileData->v1Genre)); } return 0; }// XXX : v2 tags.#if 0int ParseAudioTags(char* filename, ID3FileInf *FileData){ FILE *mp3; RMuint32 n; RMuint32 ulBytesProcessed = 0; RMuint32 BytesRead; char *pSrcFile; char *pFrameData; RMuint32 dwSize, FrameC; RMMemset(FileData, 0x00, sizeof(ID3FileInf)); mp3 = fopen(filename, "r"); if (mp3 == 0) { printf ("error: cannot open %s\n", filename); return 0; } else { fseek(mp3, 0, SEEK_END); dwSize = ftell(mp3); printf ("%s is %lu bytes long\n", filename, dwSize); printf ("Now finding and parsing tags...please wait\n"); //mmioSeek (mp3, 0, SEEK_SET); fseek(mp3, 0, SEEK_SET); } n = fread( mp3buf, sizeof( char ), 3000, mp3); ulBytesProcessed += n; fseek(mp3, dwSize-128, SEEK_SET); fread( mp3buf, sizeof( char ), 128, mp3); fseek(mp3, 0, SEEK_SET); BytesRead = 0; RMMemset(mp3buf,0x00, 5000); FrameC = 0; //Read file header //while(BytesRead != dwSize) if(1) { //n = mmioRead (mp3, (HPSTR)mp3buf, 128); n = fread( mp3buf, sizeof( char ), 128, mp3); if(n<0) { printf ("Error reading file\n"); return -1; } BytesRead += n; pSrcFile = (char *)RMMalloc(128); if(pSrcFile == NULL) { printf("Not enough memory\n"); return -1; } fseek(mp3, 0, SEEK_SET); n = fread( pSrcFile, sizeof( char ), 128, mp3); if(!memcmp(mp3buf,"RIFF",4)) { // RIFF WAVE if(!memcmp(&mp3buf[8],"WAVEfmt",7)) { printf("File is a WAV file\n"); //FileData->FileType = "Wave File"; FileData->IsWaveFile = TRUE; pFrameData = 0; if(!memcmp(&mp3buf[50],"fact",4)) { pFrameData = mp3buf + 70; } if(!memcmp(&mp3buf[52],"fact",4)) { pFrameData = mp3buf + 72; } if(!memcmp(&mp3buf[50],"data",4)) { pFrameData = mp3buf + 58; } memcpy(&(FileData->DataLen), mp3buf+4, 4); pFrameData = mp3buf + 12; memcpy(&(FileData->NumChannels), pFrameData+10, 2); FileData->SampleRate = *(RMuint32 *)(pFrameData+12); memcpy(&(FileData->AudioType), pFrameData+20, 2); memcpy(&(FileData->BitSample), pFrameData+22, 2); FileData->StartAddr = 8; FileData->EndAddr = FileData->DataLen+8; } // RIFF MP3 if(!memcmp(&mp3buf[8],"RMP3",4)) { //if(!memcmp(&pSrcFile[12],"data",4)) { pFrameData = pSrcFile + 16; } FileData->FileType = "RIFF MP3 File"; } return -1; }#ifdef ID3v2 //Check for ID3v2 Tag if((!memcmp(mp3buf,"ID3",3)) && (mp3buf[3]!=0xFF) && (mp3buf[4]!=0xFF) && ((mp3buf[5] & 0x0F) == 0)) { if((mp3buf[3] & 0x0F) == 2) { //FileData->FileType = "ID3v2 ver2.0 Tag"; FileData->HasID3v22Tag = TRUE; printf("Parsing ID3v2 ver2.0 Tag\n"); FileData->FrameSize = ((mp3buf[6] & 0x7F) << 21) | ((mp3buf[7]&0x7F)<<14) | ((mp3buf[8]&0x7F) << 7) | ((mp3buf[9]& 0x07F)); pSrcFile = (char *)RMMalloc(FileData->FrameSize+20); if(pSrcFile == NULL) { printf("Not enough memory\n"); return -1; } //mmioSeek (mp3, 0, SEEK_SET); fseek(mp3, 0, SEEK_SET); n = fread (pSrcFile, sizeof( char), 20+FileData->FrameSize, mp3 ); FrameC = 10; while(FrameC < FileData->FrameSize+10) { i = ParseFrame(pSrcFile+FrameC, FileData, 2, FrameC); FrameC += i; } FrameC = FileData->FrameSize+10; } } //Check for ID3v2 Tag if((!memcmp(mp3buf,"ID3",3)) && (mp3buf[3]!=0xFF) && (mp3buf[4]!=0xFF) && ((mp3buf[5] & 0x0F) == 0)) { if(((mp3buf[3] & 0x0F)==4) || ((mp3buf[3] & 0x0F)==3) ) { FileData->HasID3v24TagFront = TRUE; printf("Parsing ID3v2 ver 4.0 Tag\n"); FileData->FrameSize = ((mp3buf[6] & 0x7F) << 21) | ((mp3buf[7]&0x7F)<<14) | ((mp3buf[8]&0x7F) << 7) | ((mp3buf[9]& 0x07F)); if((mp3buf[5]&0x10) == 1) FileData->FooterPresent = 1; pSrcFile = (char *)RMMalloc(FileData->FrameSize+30); if(pSrcFile == NULL) { printf("Not enough memory\n"); return -1; } fseek(mp3, 0, SEEK_SET); n = fread (pSrcFile, sizeof(char), 30+FileData->FrameSize, mp3); FrameC = 10; while(FrameC < FileData->FrameSize+10) { i = ParseFrame(pSrcFile+FrameC, FileData, 4, FrameC); FrameC += i; } if(FileData->FooterPresent == 1) FrameC = FileData->FrameSize+20; else FrameC = FileData->FrameSize+10; } } if(pSrcFile[FrameC] == (char)(0xff)) { i = pSrcFile[FrameC+1]&0xf8; if( ((pSrcFile[FrameC+1]&0xf8)==0xe0) || ((pSrcFile[FrameC+1]&0xf8)==0xf0) || ((pSrcFile[FrameC+1]&0xf8)==0xf8) ) { FileData->StartAddr = FrameC; //Parse MP3 data FileData->MP3MpegSpec = ((pSrcFile[FrameC+1] & 8) == 0) ? 1 : 0; FileData->MP3Bitrate = aBitrate[ FileData->MP3MpegSpec ][ pSrcFile[FrameC+2] >> 4 ]; FileData->MP3Frequency = aFrequency[ FileData->MP3MpegSpec ][ (pSrcFile[FrameC+2] >> 2) & 3 ]; FileData->MP3Channel = (pSrcFile[FrameC+3] >> 6 == 3) ? 1 : 2; FileData->MP3FrameSize = 144000 * (FileData->MP3Bitrate / FileData->MP3Frequency); printf("MP3 Frequency %d\n", FileData->MP3Frequency); } } FrameC+=4; RMMemset(mp3buf,0x00, 5000); if(FileData->SEEKoff != 0) { //There is a second ID3v2 4.0 tag, seek to it fseek(mp3, FileData->SEEKoff, SEEK_SET); fread(&FrameC, sizeof(char), 4, mp3); fseek(mp3, FrameC, SEEK_SET); fread(mp3buf, sizeof(char), 10, mp3); FrameC+=10; //Now scan for possible appended ID3v2 tag if(!((memcmp(mp3buf,"ID3",3)==0) && (mp3buf[3]!=0xFF) && (mp3buf[4]!=0xFF) && ((mp3buf[5] & 0x0F) == 0)) && (FrameC<=dwSize)) { //Check for ID3v2 Tag if(((mp3buf[3] & 0x0F)==4) || ((mp3buf[3] & 0x0F)==3) ) { // FileData->FileType = "ID3v2 ver4.0 Tag"; FileData->HasID3v24TagEnd = TRUE; printf("Parsing appended ID3v2 ver 4.0 Tag\n"); FileData->EndAddr = FrameC; FileData->FrameSize = ((mp3buf[6] & 0x7F) << 21) | ((mp3buf[7]&0x7F)<<14) | ((mp3buf[8]&0x7F) << 7) | ((mp3buf[9]& 0x07F)); if((mp3buf[5]&0x10) == 1) FileData->FooterPresent = 1; pSrcFile = (char *)RMMalloc(FileData->FrameSize+30); if(pSrcFile == NULL) { printf("Not enough memory\n"); return -1; } fseek(mp3, 0, SEEK_SET); n = fread (pSrcFile, sizeof(char), 30+FileData->FrameSize, mp3); FrameC = 10; while(FrameC < FileData->FrameSize+10) { i = ParseFrame(pSrcFile+FrameC, FileData, 4, FrameC); FrameC += i; } } } }#endif /* ID3v2 */ RMMemset(mp3buf,0x00, 5000); //Now scan for ID3v1.1 tag fseek(mp3, dwSize-128, SEEK_SET); n= ftell(mp3); fread (mp3buf, sizeof(char), 128, mp3);#ifdef ID3v2 //Check for ID3v2 footer if((!memcmp(&mp3buf[118],"ID3",3)) && (mp3buf[121]!=0xFF) && (mp3buf[122]!=0xFF) && ((mp3buf[123] & 0x0F) == 0)) { if(((mp3buf[121] & 0x0F)==4) || ((mp3buf[121] & 0x0F)==3) ) { //FileData->FileType = "ID3v2 ver4.0 Tag"; FileData->HasID3v24TagEnd = TRUE; printf("Parsing appended ID3v2 ver 4.0 Tag\n"); //FileData->EndAddr = FrameC; FileData->FrameSize = ((mp3buf[124] & 0x7F) << 21) | ((mp3buf[125]&0x7F)<<14)| ((mp3buf[126]&0x7F) << 7) | ((mp3buf[127]& 0x07F)); FileData->FooterPresent = 1; pSrcFile = (char *)RMMalloc(FileData->FrameSize+20); if(pSrcFile == NULL) { printf("Not enough memory\n"); return -1; } fseek(mp3, (dwSize-(FileData->FrameSize+20)), SEEK_SET); n = fread (pSrcFile, sizeof(char), 20+FileData->FrameSize, mp3); FileData->EndAddr = (dwSize-(FileData->FrameSize+20)); FrameC = 10; while(FrameC < FileData->FrameSize+10){ i = ParseFrame(pSrcFile+FrameC, FileData, 4, FrameC); FrameC += i; } } }#endif /* ID3v2 */ if(!memcmp(mp3buf,"TAG",3)) { FileData->HasID3v1Tag = TRUE; printf("ID3v1 Tag found\n"); FileData->EndAddr = dwSize - 128; //Found ID3v1.1 tag memcpy(FileData->v1SongTitle, mp3buf+3, 30); printf("Song Title %s\n", FileData->v1SongTitle); memcpy(FileData->v1Artist, mp3buf+33, 30); printf("Artist %s\n", FileData->v1Artist); memcpy(FileData->v1Album, mp3buf+63, 30); printf("Album %s\n", FileData->v1Album); memcpy(FileData->v1Year, mp3buf+93, 4); printf("Year %s\n", FileData->v1Year); memcpy(FileData->v1Comment, mp3buf+97, 30); printf("Comment %s\n", FileData->v1Comment); if(mp3buf[126]!=0x00) { FileData->v1Track = mp3buf[126]; printf("Track %d\n", FileData->v1Track); } FileData->v1Genre = mp3buf[127]; printf("Genre %d\n", FileData->v1Genre); } else FileData->EndAddr = dwSize; RMMemset(mp3buf,0x00, 5000); //Now scan for ID3v1.1 tag //mmioSeek (mp3, 128, SEEK_END); fseek(mp3, dwSize-256, SEEK_SET); n= ftell(mp3); fread (mp3buf, sizeof(char), 128, mp3);#ifdef ID3v2 //Check for ID3v2 footer if((!memcmp(&mp3buf[118],"ID3",3)) && (mp3buf[121]!=0xFF) && (mp3buf[122]!=0xFF) && ((mp3buf[123] & 0x0F) == 0)) { if(((mp3buf[121] & 0x0F)==4) || ((mp3buf[121] & 0x0F)==3) ){ // FileData->FileType = "ID3v2 ver4.0 Tag"; FileData->HasID3v24TagEnd = TRUE; printf("Parsing appended ID3v2 ver 4.0 Tag\n"); //FileData->EndAddr = FrameC; FileData->FrameSize = ((mp3buf[124] & 0x7F) << 21) | ((mp3buf[125]&0x7F)<<14) | ((mp3buf[126]&0x7F) << 7) | ((mp3buf[127]& 0x07F)); FileData->FooterPresent = 1; pSrcFile = (char *)RMMalloc(FileData->FrameSize+20); if(pSrcFile == NULL){ printf("Not enough memory\n"); return -1; } //n = mmioRead (mp3, (HPSTR)pSrcFile, 30+FileData->FrameSize); fseek(mp3, (dwSize-(FileData->FrameSize+20+128)), SEEK_SET); n = fread (pSrcFile, sizeof(char), 20+FileData->FrameSize, mp3); FileData->EndAddr = (dwSize-(FileData->FrameSize+20+128)); FrameC = 10; while(FrameC < FileData->FrameSize+10){ i = ParseFrame(pSrcFile+FrameC, FileData, 4, FrameC); FrameC += i; } } }#endif /* ID3v2 */ } RMFree(pSrcFile); //RMFree(FileData); fclose(mp3); return 0;}#ifdef ID3v2// Function that parses a frame// Returns the number of bytes parsedint ParseFrame(char *pData, ID3FileInf *pStruct, int version, int pos){ char buf[256]; char name[256]; RMuint32 i, num, FrameC, len; if(version == 2) { FrameC = 0; memcpy(buf, pData, 3); FrameC+=3; //memcpy(&(num), pData+FrameC, 3); num = (pData[FrameC]<< 16) | (pData[FrameC+1]<<8) | (pData[FrameC+2]); FrameC+=3; if(!memcmp("TT1", buf, 3)) { pStruct->TT1off = pos+FrameC; pStruct->TT1len = num; FrameC+=num; return FrameC; } if(!memcmp("TT2", buf, 3)) { pStruct->TT2off = pos+FrameC; pStruct->TT2len = num; FrameC+=num; return FrameC; } if(!memcmp("TT3", buf, 3)) { pStruct->TT3off = pos+FrameC; pStruct->TT3len = num; FrameC+=num; return FrameC; } if(!memcmp("TP1", buf, 3)) { pStruct->TP1off = pos+FrameC; pStruct->TP1len = num; FrameC+=num; return FrameC; } if(!memcmp("TP2", buf, 3)) { pStruct->TP2off = pos+FrameC; pStruct->TP2len = num; FrameC+=num; return FrameC; } if(!memcmp("TP3", buf, 3)) { pStruct->TP3off = pos+FrameC; pStruct->TP3len = num; FrameC+=num; return FrameC; } if(!memcmp("TP4", buf, 3)) { pStruct->TP4off = pos+FrameC; pStruct->TP4len = num; FrameC+=num; return FrameC; } if(!memcmp("TCM", buf, 3)) { pStruct->TCMoff = pos+FrameC; pStruct->TCMlen = num; FrameC+=num; return FrameC; } if(!memcmp("TXT", buf, 3)) { pStruct->TXToff = pos+FrameC; pStruct->TXTlen = num; FrameC+=num; return FrameC;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -