void GetTestTag(void) { ID3_Tag myTag("dummy.tag"); ID3_Frame *myFrame; if (myFrame = myTag.Find(ID3FID_PICTURE)) { cout << "Found a picture frame!\r\n" << endl; char *dada = "output.jpg"; myFrame->Field(ID3FN_DATA).ToFile(dada); } if (myFrame = myTag.Find(ID3FID_USERTEXT, ID3FN_DESCRIPTION, "example #1")) { cout << "Found a user text frame!\r\n" << endl; char textBuff[1024]; myFrame->Field(ID3FN_DESCRIPTION).Get(textBuff, 1024); cout << "Desc: " << textBuff << endl; myFrame->Field(ID3FN_TEXT).Get(textBuff, 1024); cout << "Text: " << textBuff << endl; } for (luint i = 0; i < myTag.NumFrames(); i++) if (myFrame = myTag[i]) cout << "Frame " << i << " has ID " << (luint) myFrame->GetID() << endl; return; }
ID3_Frame *ID3_Tag::Find( ID3_FrameID id, ID3_FieldID fld, wchar_t *data ) { ID3_Frame *frame = NULL; ID3_Elem *cur = findCursor; bool done = false; if ( cur == NULL ) findCursor = cur = frameList; while ( ! done && cur ) { if ( cur->frame && ( cur->frame->GetID() == id ) ) { frame = cur->frame; if ( data && wcslen ( data ) && BS_ISSET ( frame->fieldBits, fld ) ) { wchar_t *buffer; luint size; size = frame->Field ( fld ).BinSize(); #ifdef _DEBUG //ASSERT( size < MAX_ALLOC ); // PL #endif buffer = new wchar_t[size]; { frame->Field ( fld ).Get(buffer, size); if(wcscmp(buffer, data) != 0 ) { frame = NULL; cur = cur->next; } delete[] buffer; } } if ( frame ) { findCursor = cur->next; break; } } else cur = cur->next; if ( cur == NULL ) cur = frameList; if ( cur == findCursor ) done = true; } return frame; }
ID3_Frame* ID3_AddComment(ID3_Tag *tag, const char *sComment, const char *sDescription, bool bReplace) { ID3_Frame* pFrame = NULL; if (NULL != tag && NULL != sComment && NULL != sDescription && strlen(sComment) > 0) { bool bAdd = true; if (bReplace) { ID3_RemoveComments(tag, sDescription); } else { // See if there is already a comment with this description for (size_t nCount = 0; nCount < tag->NumFrames(); nCount++) { pFrame = tag->GetFrameNum(nCount); if (pFrame->GetID() == ID3FID_COMMENT) { char *sDesc = ID3_GetString(pFrame, ID3FN_DESCRIPTION); if (strcmp(sDesc, sDescription) == 0) { bAdd = false; } delete [] sDesc; if (!bAdd) { break; } } } } if (bAdd) { pFrame = new ID3_Frame(ID3FID_COMMENT); if (NULL != pFrame) { pFrame->Field(ID3FN_LANGUAGE) = "eng"; pFrame->Field(ID3FN_DESCRIPTION) = sDescription; pFrame->Field(ID3FN_TEXT) = sComment; tag->AttachFrame(pFrame); } } } return pFrame; }
ID3_Frame* ID3_AddGenre(ID3_Tag *tag, size_t ucGenre, bool bReplace) { ID3_Frame* pFrame = NULL; if (NULL != tag && 0xFF != ucGenre) { if (bReplace) { ID3_RemoveGenres(tag); } if (bReplace || NULL == tag->Find(ID3FID_CONTENTTYPE)) { pFrame = new ID3_Frame(ID3FID_CONTENTTYPE); if (NULL != pFrame) { char sGenre[6]; sprintf(sGenre, "(%lu)", (luint) ucGenre); pFrame->Field(ID3FN_TEXT) = sGenre; tag->AttachFrame(pFrame); } } } return pFrame; }
ID3_Frame* ID3_AddArtist(ID3_Tag *tag, const char *text, bool bReplace) { ID3_Frame* pFrame = NULL; if (NULL != tag && NULL != text && strlen(text) > 0) { if (bReplace) { ID3_RemoveArtists(tag); } if (bReplace || (tag->Find(ID3FID_LEADARTIST) == NULL && tag->Find(ID3FID_BAND) == NULL && tag->Find(ID3FID_CONDUCTOR) == NULL && tag->Find(ID3FID_COMPOSER) == NULL)) { pFrame = new ID3_Frame(ID3FID_LEADARTIST); if (pFrame) { pFrame->Field(ID3FN_TEXT) = text; tag->AttachFrame(pFrame); } } } return pFrame; }
int CMP4Tag::ReadAacTag(char *Filename) { char *buf=NULL; ID3_Tag id3Tag; ID3_Frame *Frame; if(!id3Tag.Link(Filename)) { char buf[25+MAX_PATH+1]; sprintf(buf,"ReadAacTag: can't open \"%s\"",Filename); MessageBox(NULL,buf,NULL,MB_OK); return 1; } GET_FIELD_STR(id3Tag,ID3FID_ENCODEDBY,ID3FN_TEXT,copyright); GET_FIELD_STR(id3Tag,ID3FID_LEADARTIST,ID3FN_TEXT,artist); GET_FIELD_STR(id3Tag,ID3FID_COMPOSER,ID3FN_TEXT,writer); GET_FIELD_STR(id3Tag,ID3FID_TITLE,ID3FN_TEXT,title); GET_FIELD_STR(id3Tag,ID3FID_ALBUM,ID3FN_TEXT,album); GET_FIELD_STR(id3Tag,ID3FID_TRACKNUM,ID3FN_TEXT,buf); if(buf) trackno=atoi(buf); FREE_ARRAY(buf); GET_FIELD_STR(id3Tag,ID3FID_YEAR,ID3FN_TEXT,year); GET_FIELD_STR(id3Tag,ID3FID_CONTENTTYPE,ID3FN_TEXT,genre); GET_FIELD_STR(id3Tag,ID3FID_COMMENT,ID3FN_TEXT,comment); if(Frame=id3Tag.Find(ID3FID_PICTURE)) { art.size=Frame->Field(ID3FN_DATA).Size(); FREE_ARRAY(art.data); if(art.data=(char *)malloc(art.size)) memcpy(art.data,Frame->Field(ID3FN_DATA).GetBinary(),art.size); GET_FIELD_STR(id3Tag,ID3FID_PICTURE,ID3FN_MIMETYPE,art.mimeType); GET_FIELD_STR(id3Tag,ID3FID_PICTURE,ID3FN_DESCRIPTION,art.description); GET_FIELD_STR(id3Tag,ID3FID_PICTURE,ID3FN_IMAGEFORMAT,art.format); art.pictureType=Frame->Field(ID3FN_PICTURETYPE).Get(); /* FILE *f=fopen("D:\\prova.jpg","wb"); fwrite(artFile,1,artSize,f); fclose(f);*/ } return 0; }
ID3_Frame* ID3_AddSyncLyrics(ID3_Tag *tag, const char *lang, const char *desc, const uchar *text, size_t textsize, bool bReplace) { ID3_Frame* pFrame = NULL; // language and descriptor should be mandatory if ((NULL == lang) || (NULL == desc)) { return NULL; } // check if a SYLT frame of this language or descriptor already exists ID3_Frame* pFrameExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, (char *) lang); if (!pFrameExist) { pFrameExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, (char *) desc); } if (NULL != tag && NULL != text) { if (bReplace && pFrameExist) { tag->RemoveFrame (pFrameExist); pFrameExist = NULL; } // if the frame still exist, cannot continue if (pFrameExist) { return NULL; } ID3_Frame* pFrame = new ID3_Frame(ID3FID_SYNCEDLYRICS); if (NULL == pFrame) { ID3_THROW(ID3E_NoMemory); } pFrame->Field(ID3FN_LANGUAGE) = lang; pFrame->Field(ID3FN_DESCRIPTION) = desc; pFrame->Field(ID3FN_DATA).Set(text, textsize); tag->AttachFrame(pFrame); } return pFrame; }
void ID3_AddLyrics( ID3_Tag *tag, char *text ) { if ( tag->Find ( ID3FID_UNSYNCEDLYRICS ) == NULL && strlen ( text ) > 0 ) { ID3_Frame *lyricsFrame; if ( lyricsFrame = new ID3_Frame ) { lyricsFrame->SetID ( ID3FID_UNSYNCEDLYRICS ); lyricsFrame->Field ( ID3FN_LANGUAGE ) = "eng"; lyricsFrame->Field ( ID3FN_TEXT ) = text; tag->AddFrame ( lyricsFrame, true ); } else ID3_THROW ( ID3E_NoMemory ); } return; }
ID3_Frame *ID3_GetSyncLyricsInfo(const ID3_Tag *tag, const char *lang, const char *desc, size_t& stampformat, size_t& type, size_t& size) { // check if a SYLT frame of this language or descriptor exists ID3_Frame* pFrameExist = NULL; if (NULL != lang) { // search through language pFrameExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang); } else if (NULL != desc) { // search through descriptor pFrameExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc); } else { // both language and description not specified, search the first SYLT frame pFrameExist = tag->Find(ID3FID_SYNCEDLYRICS); } if (!pFrameExist) { return NULL; } // get the lyrics time stamp format stampformat = pFrameExist->Field (ID3FN_TIMESTAMPFORMAT).Get (); // get the lyrics content type type = pFrameExist->Field (ID3FN_CONTENTTYPE).Get (); // get the lyrics size size = pFrameExist->Field (ID3FN_DATA).Size (); // return the frame pointer for further uses return pFrameExist; }
ID3_Frame* ID3_AddLyrics(ID3_Tag *tag, const char *text, bool bReplace) { ID3_Frame* pFrame = NULL; if (NULL != tag && strlen(text) > 0) { if (bReplace) { ID3_RemoveLyrics(tag); } if (bReplace || tag->Find(ID3FID_UNSYNCEDLYRICS) == NULL) { pFrame = new ID3_Frame(ID3FID_UNSYNCEDLYRICS); if (NULL != pFrame) { pFrame->Field(ID3FN_LANGUAGE) = "eng"; pFrame->Field(ID3FN_TEXT) = text; tag->AttachFrame(pFrame); } } } return pFrame; }
ID3_Frame *ID3_GetSyncLyrics(const ID3_Tag *tag, const char *lang, const char *desc, const uchar *pData, size_t& size) { // check if a SYLT frame of this language or descriptor exists ID3_Frame* pFrameExist = NULL; if (NULL != lang) { // search through language pFrameExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_LANGUAGE, lang); } else if (NULL != desc) { // search through descriptor pFrameExist = tag->Find(ID3FID_SYNCEDLYRICS, ID3FN_DESCRIPTION, desc); } else { // both language and description not specified, search the first SYLT frame pFrameExist = tag->Find(ID3FID_SYNCEDLYRICS); } if (NULL == pFrameExist) { return NULL; } // get the lyrics size size_t datasize = pFrameExist->Field(ID3FN_DATA).Size(); size = MIN(size, datasize); // get the lyrics data pData = pFrameExist->Field (ID3FN_DATA).GetBinary(); // return the frame pointer for further uses return pFrameExist; }
ID3_Frame* ID3_AddMCDI(ID3_Tag *tag, const char *text, bool bReplace) { ID3_Frame* pFrame = NULL; if (NULL != tag && NULL != text && strlen(text) > 0) { if (bReplace) { ID3_RemoveMCDI(tag); } if (bReplace || tag->Find(ID3FID_CDID) == NULL) { pFrame = new ID3_Frame( ID3FID_CDID ); if (pFrame) { const int nMaxTagLength = 804; size_t nStrLen = strlen( text ); uchar *temp = new uchar[ nMaxTagLength + 1 ]; memset( temp, sizeof( temp ), 0 ); if ( NULL == temp ) { // AF ID3_THROW( ID3E_NoMemory ); } memset( temp, 0x00, sizeof( temp ) ); //fixes 99 tracks bug if( nStrLen > nMaxTagLength / 2 ) { nStrLen = nMaxTagLength / 2; } // mbstoucs( (unicode_t *)temp, text, nStrLen + 1 ); pFrame->Field(ID3FN_DATA).Set( temp, nMaxTagLength ); // delete[] temp; tag->AttachFrame( pFrame ); } } } return pFrame; }
void ID3_AddAlbum ( ID3_Tag *tag, char *text ) { if ( tag->Find ( ID3FID_ALBUM ) == NULL && strlen ( text ) > 0 ) { ID3_Frame *albumFrame; if ( albumFrame = new ID3_Frame ) { albumFrame->SetID ( ID3FID_ALBUM ); albumFrame->Field ( ID3FN_TEXT ) = text; tag->AddFrame ( albumFrame, true ); } else ID3_THROW ( ID3E_NoMemory ); } return; }
void ID3_AddTitle ( ID3_Tag *tag, char *text ) { if ( tag->Find ( ID3FID_TITLE ) == NULL && strlen ( text ) > 0 ) { ID3_Frame *titleFrame; if ( titleFrame = new ID3_Frame ) { titleFrame->SetID ( ID3FID_TITLE ); titleFrame->Field ( ID3FN_TEXT ) = text; tag->AddFrame ( titleFrame, true ); } else ID3_THROW ( ID3E_NoMemory ); } return; }
ID3_Frame* ID3_AddSongLen(ID3_Tag *tag, const char *text, bool bReplace) { ID3_Frame* pFrame = NULL; if (NULL != tag && NULL != text && strlen(text) > 0) { if (bReplace) { ID3_RemoveSongLen( tag ); } if (bReplace || tag->Find(ID3FID_SONGLEN) == NULL) { pFrame = new ID3_Frame(ID3FID_SONGLEN); if (pFrame) { pFrame->Field(ID3FN_TEXT) = text; tag->AttachFrame(pFrame); } } } return pFrame; }
void ID3_AddArtist ( ID3_Tag *tag, char *text ) { if ( tag->Find ( ID3FID_LEADARTIST ) == NULL && tag->Find ( ID3FID_BAND ) == NULL && tag->Find ( ID3FID_CONDUCTOR ) == NULL && tag->Find ( ID3FID_COMPOSER ) == NULL && strlen ( text ) > 0 ) { ID3_Frame *artistFrame; if ( artistFrame = new ID3_Frame ) { artistFrame->SetID ( ID3FID_LEADARTIST ); artistFrame->Field ( ID3FN_TEXT ) = text; tag->AddFrame ( artistFrame, true ); } else ID3_THROW ( ID3E_NoMemory ); } return; }
char *ID3_GetMCDI(const ID3_Tag *tag) { char *sComment = NULL; uchar temp[ 805 ]; memset( temp, 0, sizeof( temp ) ); if (NULL == tag) { return sComment; } ID3_Frame *pFrame = tag->Find(ID3FID_CDID); if (pFrame != NULL) { int nStrLen = 0; //sComment = ID3_GetString(pFrame, ID3FN_TEXT); char *sComment = new char[ 805 ]; memset( sComment, sizeof( sComment ), 0 ); if ( NULL == temp ) { // AF ID3_THROW(ID3E_NoMemory); } pFrame->Field(ID3FN_DATA).Get( temp, 804 ); nStrLen = ucslen( (unicode_t *) temp ); // ucstombs( sComment, (unicode_t *)temp, nStrLen + 1 ); } return sComment; }
ID3_Frame *ID3_Tag::Find ( ID3_FrameID id, ID3_FieldID fld, luint data ) { ID3_Frame *frame = NULL; ID3_Elem *cur = findCursor; bool done = false; if ( cur == NULL ) findCursor = cur = frameList; while ( ! done && cur ) { if ( cur->frame && ( cur->frame->GetID() == id ) ) { frame = cur->frame; if ( frame->Field ( fld ).Get() != data ) { frame = NULL; cur = cur->next; } if ( frame ) { findCursor = cur->next; break; } } else cur = cur->next; if ( cur == NULL ) cur = frameList; if ( cur == findCursor ) done = true; } return frame; }
ID3_Frame* ID3_AddLyricist(ID3_Tag *tag, const char *text, bool bReplace) { ID3_Frame* pFrame = NULL; if (NULL != tag && NULL != text && strlen(text) > 0) { if (bReplace) { ID3_RemoveLyricist(tag); } if (bReplace || (tag->Find(ID3FID_LYRICIST) == NULL)) { pFrame = new ID3_Frame(ID3FID_LYRICIST); if (pFrame) { pFrame->Field(ID3FN_TEXT) = text; tag->AttachFrame(pFrame); } } } return pFrame; }
ID3_Frame* ID3_AddEncodedBy(ID3_Tag *tag, const char *text, bool bReplace) { ID3_Frame* pFrame = NULL; if (NULL != tag && NULL != text && strlen(text) > 0) { if (bReplace) { ID3_RemoveEncodedBy(tag); } if (bReplace || tag->Find(ID3FID_ENCODEDBY) == NULL) { pFrame = new ID3_Frame(ID3FID_ENCODEDBY); if (pFrame) { pFrame->Field(ID3FN_TEXT) = text; tag->AttachFrame(pFrame); } } } return pFrame; }
ID3_Frame* ID3_AddTrack(ID3_Tag *tag, uchar ucTrack, uchar ucTotal, bool bReplace) { ID3_Frame* pFrame = NULL; if (NULL != tag && ucTrack > 0) { if (bReplace) { ID3_RemoveTracks(tag); } if (bReplace || NULL == tag->Find(ID3FID_TRACKNUM)) { ID3_Frame *trackFrame = new ID3_Frame(ID3FID_TRACKNUM); if (trackFrame) { char *sTrack = NULL; if (0 == ucTotal) { sTrack = new char[4]; sprintf(sTrack, "%lu", (luint) ucTrack); } else { sTrack = new char[8]; sprintf(sTrack, "%lu/%lu", (luint) ucTrack, (luint) ucTotal); } trackFrame->Field(ID3FN_TEXT) = sTrack; tag->AttachFrame(trackFrame); delete [] sTrack; } } } return pFrame; }
int main( int argc, char *argv[]) { int iOpt; int argCounter = 0; int ii; char tmp[TMPSIZE]; FILE * fp; struct frameInfo { enum ID3_FrameID id; char *data; } frameList[MAXNOFRAMES]; int frameCounter = 0; while (true) { int option_index = 0; int iLongOpt = 0; int optFrameID = ID3FID_NOFRAME; static struct option long_options[] = { // help and info { "help", no_argument, &iLongOpt, 'h' }, { "list-frames", no_argument, &iLongOpt, 'f' }, { "list-genres", no_argument, &iLongOpt, 'L' }, { "version", no_argument, &iLongOpt, 'v' }, // list / remove / convert { "list", no_argument, &iLongOpt, 'l' }, { "list-rfc822", no_argument, &iLongOpt, 'R' }, { "delete-v2", no_argument, &iLongOpt, 'd' }, { "delete-v1", no_argument, &iLongOpt, 's' }, { "delete-all", no_argument, &iLongOpt, 'D' }, { "convert", no_argument, &iLongOpt, 'C' }, { "id3v1-only", no_argument, &iLongOpt, '1' }, { "id3v2-only", no_argument, &iLongOpt, '2' }, // infomation to tag { "artist", required_argument, &iLongOpt, 'a' }, { "album", required_argument, &iLongOpt, 'A' }, { "song", required_argument, &iLongOpt, 't' }, { "comment", required_argument, &iLongOpt, 'c' }, { "genre", required_argument, &iLongOpt, 'g' }, { "year", required_argument, &iLongOpt, 'y' }, { "track", required_argument, &iLongOpt, 'T' }, { "AENC", required_argument, &optFrameID, ID3FID_AUDIOCRYPTO }, { "APIC", required_argument, &optFrameID, ID3FID_PICTURE }, { "COMM", required_argument, &optFrameID, ID3FID_COMMENT }, /* COMR too complex */ { "ENCR", required_argument, &optFrameID, ID3FID_CRYPTOREG }, { "EQUA", required_argument, &optFrameID, ID3FID_EQUALIZATION }, { "ETCO", required_argument, &optFrameID, ID3FID_EVENTTIMING }, { "GEOB", required_argument, &optFrameID, ID3FID_GENERALOBJECT }, { "GRID", required_argument, &optFrameID, ID3FID_GROUPINGREG }, { "IPLS", required_argument, &optFrameID, ID3FID_INVOLVEDPEOPLE }, { "LINK", required_argument, &optFrameID, ID3FID_LINKEDINFO }, { "MCDI", required_argument, &optFrameID, ID3FID_CDID }, { "MLLT", required_argument, &optFrameID, ID3FID_MPEGLOOKUP }, { "OWNE", required_argument, &optFrameID, ID3FID_OWNERSHIP }, { "PRIV", required_argument, &optFrameID, ID3FID_PRIVATE }, { "PCNT", required_argument, &optFrameID, ID3FID_PLAYCOUNTER }, { "POPM", required_argument, &optFrameID, ID3FID_POPULARIMETER }, { "POSS", required_argument, &optFrameID, ID3FID_POSITIONSYNC }, { "RBUF", required_argument, &optFrameID, ID3FID_BUFFERSIZE }, { "RVAD", required_argument, &optFrameID, ID3FID_VOLUMEADJ }, { "RVRB", required_argument, &optFrameID, ID3FID_REVERB }, { "SYLT", required_argument, &optFrameID, ID3FID_SYNCEDLYRICS }, { "SYTC", required_argument, &optFrameID, ID3FID_SYNCEDTEMPO }, { "TALB", required_argument, &optFrameID, ID3FID_ALBUM }, { "TBPM", required_argument, &optFrameID, ID3FID_BPM }, { "TCOM", required_argument, &optFrameID, ID3FID_COMPOSER }, { "TCON", required_argument, &optFrameID, ID3FID_CONTENTTYPE }, { "TCOP", required_argument, &optFrameID, ID3FID_COPYRIGHT }, { "TDAT", required_argument, &optFrameID, ID3FID_DATE }, { "TDLY", required_argument, &optFrameID, ID3FID_PLAYLISTDELAY }, { "TENC", required_argument, &optFrameID, ID3FID_ENCODEDBY }, { "TEXT", required_argument, &optFrameID, ID3FID_LYRICIST }, { "TFLT", required_argument, &optFrameID, ID3FID_FILETYPE }, { "TIME", required_argument, &optFrameID, ID3FID_TIME }, { "TIT1", required_argument, &optFrameID, ID3FID_CONTENTGROUP }, { "TIT2", required_argument, &optFrameID, ID3FID_TITLE }, { "TIT3", required_argument, &optFrameID, ID3FID_SUBTITLE }, { "TKEY", required_argument, &optFrameID, ID3FID_INITIALKEY }, { "TLAN", required_argument, &optFrameID, ID3FID_LANGUAGE }, { "TLEN", required_argument, &optFrameID, ID3FID_SONGLEN }, { "TMED", required_argument, &optFrameID, ID3FID_MEDIATYPE }, { "TOAL", required_argument, &optFrameID, ID3FID_ORIGALBUM }, { "TOFN", required_argument, &optFrameID, ID3FID_ORIGFILENAME }, { "TOLY", required_argument, &optFrameID, ID3FID_ORIGLYRICIST }, { "TOPE", required_argument, &optFrameID, ID3FID_ORIGARTIST }, { "TORY", required_argument, &optFrameID, ID3FID_ORIGYEAR }, { "TOWN", required_argument, &optFrameID, ID3FID_FILEOWNER }, { "TPE1", required_argument, &optFrameID, ID3FID_LEADARTIST }, { "TPE2", required_argument, &optFrameID, ID3FID_BAND }, { "TPE3", required_argument, &optFrameID, ID3FID_CONDUCTOR }, { "TPE4", required_argument, &optFrameID, ID3FID_MIXARTIST }, { "TPOS", required_argument, &optFrameID, ID3FID_PARTINSET }, { "TPUB", required_argument, &optFrameID, ID3FID_PUBLISHER }, { "TRCK", required_argument, &optFrameID, ID3FID_TRACKNUM }, { "TRDA", required_argument, &optFrameID, ID3FID_RECORDINGDATES }, { "TRSN", required_argument, &optFrameID, ID3FID_NETRADIOSTATION }, { "TRSO", required_argument, &optFrameID, ID3FID_NETRADIOOWNER }, { "TSIZ", required_argument, &optFrameID, ID3FID_SIZE }, { "TSRC", required_argument, &optFrameID, ID3FID_ISRC }, { "TSSE", required_argument, &optFrameID, ID3FID_ENCODERSETTINGS }, { "TXXX", required_argument, &optFrameID, ID3FID_USERTEXT }, { "TYER", required_argument, &optFrameID, ID3FID_YEAR }, { "UFID", required_argument, &optFrameID, ID3FID_UNIQUEFILEID }, { "USER", required_argument, &optFrameID, ID3FID_TERMSOFUSE }, { "USLT", required_argument, &optFrameID, ID3FID_UNSYNCEDLYRICS }, { "WCOM", required_argument, &optFrameID, ID3FID_WWWCOMMERCIALINFO }, { "WCOP", required_argument, &optFrameID, ID3FID_WWWCOPYRIGHT }, { "WOAF", required_argument, &optFrameID, ID3FID_WWWAUDIOFILE }, { "WOAR", required_argument, &optFrameID, ID3FID_WWWARTIST }, { "WOAS", required_argument, &optFrameID, ID3FID_WWWAUDIOSOURCE }, { "WORS", required_argument, &optFrameID, ID3FID_WWWRADIOPAGE }, { "WPAY", required_argument, &optFrameID, ID3FID_WWWPAYMENT }, { "WPUB", required_argument, &optFrameID, ID3FID_WWWPUBLISHER }, { "WXXX", required_argument, &optFrameID, ID3FID_WWWUSER }, { 0, 0, 0, 0 } }; iOpt = getopt_long (argc, argv, "12hfLvlRdsDCa:A:t:c:g:y:T:", long_options, &option_index); if (iOpt == -1 && argCounter == 0) { PrintUsage(argv[0]); exit(0); } else if (iOpt == -1) break; argCounter++; if (iOpt == 0) iOpt = iLongOpt; // if (iOpt == 0) iOpt = optFrameID; #ifdef SORT_RUNTIME InitGenres(); #endif // SORT_RUNTIME switch (iOpt) { case 0: frameList[frameCounter].id = (enum ID3_FrameID)optFrameID; frameList[frameCounter].data = optarg; frameCounter++; break; case '?': case 'h': PrintUsage(argv[0]); exit (0); case 'f': PrintFrameHelp(argv[0]);exit (0); case 'L': PrintGenreList(); exit (0); case 'v': PrintVersion(argv[0]); exit (0); // listing / remove / convert -- see list.cpp and convert.cpp case 'l': ListTag(argc, argv, optind, 0); exit (0); case 'R': ListTag(argc, argv, optind, 1); exit (0); case 'd': DeleteTag(argc, argv, optind, 2); exit (0); case 's': DeleteTag(argc, argv, optind, 1); exit (0); case 'D': DeleteTag(argc, argv, optind, 0); exit (0); case 'C': ConvertTag(argc, argv, optind); exit (0); case '1': UpdFlags = ID3TT_ID3V1; break; case '2': UpdFlags = ID3TT_ID3V2; break; // Tagging stuff case 'a': frameList[frameCounter].id = ID3FID_LEADARTIST; frameList[frameCounter].data = optarg; frameCounter++; break; case 'A': frameList[frameCounter].id = ID3FID_ALBUM; frameList[frameCounter].data = optarg; frameCounter++; break; case 't': frameList[frameCounter].id = ID3FID_TITLE; frameList[frameCounter].data = optarg; frameCounter++; break; case 'c': frameList[frameCounter].id = ID3FID_COMMENT; frameList[frameCounter].data = optarg; frameCounter++; break; case 'g': { int genre_id = 255; char *genre_str; sscanf(optarg, "%d", &genre_id); if (genre_id == 255) genre_id = GetNumFromGenre(optarg); if (genre_id == 255) genre_str = optarg; else { sprintf(tmp, "(%d)", genre_id); genre_str = tmp; } frameList[frameCounter].id = ID3FID_CONTENTTYPE; frameList[frameCounter].data = genre_str; frameCounter++; } break; case 'y': frameList[frameCounter].id = ID3FID_YEAR; frameList[frameCounter].data = optarg; frameCounter++; break; case 'T': frameList[frameCounter].id = ID3FID_TRACKNUM; frameList[frameCounter].data = optarg; frameCounter++; break; // other tags default: std::cerr << "This isn't supposed to happen" << std::endl; exit(1); } } // loop thru the files if (optind == argc) { std::cerr << "No file to work on." << std::endl; exit(1); } for (size_t nIndex = optind; (unsigned int) nIndex < argc; nIndex++) { ID3_Tag myTag; struct stat filestat; // std::cout << "Tagging " << argv[nIndex] << ": "; // fix me - not checking to see if we can link to it if (stat(argv[nIndex], &filestat)) { std::cerr << "Couldn't stat file '" << argv[nIndex] << "'\n"; break; } /* cludgy to check if we have the proper perms */ fp = fopen(argv[nIndex], "r+"); if (fp == NULL) { /* file didn't open */ fprintf(stderr, "fopen: %s: ", argv[nIndex]); perror("id3v2"); continue; } fclose(fp); size_t ret; ret = myTag.Link(argv[nIndex] /*, ID3TT_ID3V2 */); // loop thru the frames we need to add/modify for (ii = 0; ii < frameCounter; ii++) { ID3_Frame *myFrame; myFrame = new ID3_Frame; if (NULL == myFrame) { std::cout << "\nOut of memory\n" << std::endl; exit(1); } myFrame->SetID(frameList[ii].id); ID3_Frame *pFrame; pFrame = myTag.Find(frameList[ii].id); switch (frameList[ii].id) { // strings case ID3FID_ALBUM: case ID3FID_BPM: case ID3FID_COMPOSER: case ID3FID_CONTENTTYPE: case ID3FID_COPYRIGHT: case ID3FID_DATE: case ID3FID_PLAYLISTDELAY: case ID3FID_ENCODEDBY: case ID3FID_LYRICIST: case ID3FID_FILETYPE: case ID3FID_TIME: case ID3FID_CONTENTGROUP: case ID3FID_TITLE: case ID3FID_SUBTITLE: case ID3FID_INITIALKEY: case ID3FID_LANGUAGE: case ID3FID_SONGLEN: case ID3FID_MEDIATYPE: case ID3FID_ORIGALBUM: case ID3FID_ORIGFILENAME: case ID3FID_ORIGLYRICIST: case ID3FID_ORIGARTIST: case ID3FID_ORIGYEAR: case ID3FID_FILEOWNER: case ID3FID_LEADARTIST: case ID3FID_BAND: case ID3FID_CONDUCTOR: case ID3FID_MIXARTIST: case ID3FID_PARTINSET: case ID3FID_PUBLISHER: case ID3FID_RECORDINGDATES: case ID3FID_NETRADIOSTATION: case ID3FID_NETRADIOOWNER: case ID3FID_SIZE: case ID3FID_ISRC: case ID3FID_ENCODERSETTINGS: case ID3FID_YEAR: { if (pFrame != NULL) { myTag.RemoveFrame(pFrame); } if (strlen(frameList[ii].data) > 0) { myFrame->Field(ID3FN_TEXT) = frameList[ii].data; myTag.AttachFrame(myFrame); } break; } case ID3FID_TRACKNUM: { // this ought to check if there is a total track number and // combine it with the given track number, but it doesn't. char *currentTrackNum = NULL; char *newTrackNum = NULL; if (pFrame != NULL) { currentTrackNum = ID3_GetString(pFrame, ID3FN_TEXT); if (*currentTrackNum == '/') { newTrackNum = (char *)malloc(strlen(currentTrackNum) + strlen(frameList[ii].data)); strcpy(newTrackNum, frameList[ii].data); strcat(newTrackNum, currentTrackNum); } else { myTag.RemoveFrame(pFrame); } } myFrame->Field(ID3FN_TEXT) = frameList[ii].data; myTag.AttachFrame(myFrame); free(newTrackNum); break; } case ID3FID_USERTEXT: { if (pFrame != NULL) { myTag.RemoveFrame(pFrame); } // split the string at the ':' remember if no : then leave // descrip empty char *text; text = strchr(frameList[ii].data, ':'); if (text == NULL) { myFrame->Field(ID3FN_TEXT) = frameList[ii].data; } else { *text = '\0'; text++; myFrame->Field(ID3FN_DESCRIPTION) = frameList[ii].data; myFrame->Field(ID3FN_TEXT) = text; } if (strlen(ID3_GetString(myFrame, ID3FN_TEXT)) > 0) { myTag.AttachFrame(myFrame); } break; } case ID3FID_COMMENT: case ID3FID_UNSYNCEDLYRICS: { // split the string at the ':' remember if no : then leave // descrip/lang empty char *text; text = strchr(frameList[ii].data, ':'); if (text == NULL) { myFrame->Field(ID3FN_TEXT) = frameList[ii].data; } else { *text = '\0'; text++; char *lang; lang = strchr(text, ':'); if (lang == NULL) { myFrame->Field(ID3FN_DESCRIPTION) = frameList[ii].data; myFrame->Field(ID3FN_TEXT) = text; } else { *lang = '\0'; lang++; myFrame->Field(ID3FN_DESCRIPTION) = frameList[ii].data; myFrame->Field(ID3FN_TEXT) = text; myFrame->Field(ID3FN_LANGUAGE) = lang; } } /* debug std::cout << ID3_GetString(myFrame, ID3FN_DESCRIPTION) << std::endl << ID3_GetString(myFrame, ID3FN_TEXT) << std::endl << ID3_GetString(myFrame, ID3FN_LANGUAGE) << std::endl; */ // now try and find a comment/lyrics with the same descript // and lang as what we have ID3_Frame *pFirstFrame = NULL; do { // if pFrame is NULL, either there were no comments/lyrics // to begin with, or we removed them all in the process if (pFrame == NULL) break; if (pFirstFrame == NULL) { pFirstFrame = pFrame; } char *tmp_desc = ID3_GetString(pFrame, ID3FN_DESCRIPTION); char *tmp_my_desc = ID3_GetString(myFrame, ID3FN_DESCRIPTION); char *tmp_lang = ID3_GetString(pFrame, ID3FN_LANGUAGE); char *tmp_my_lang = ID3_GetString(myFrame, ID3FN_LANGUAGE); if ((strcmp(tmp_desc, tmp_my_desc) == 0) && (strcmp(tmp_lang, tmp_my_lang) == 0)) { myTag.RemoveFrame(pFrame); if (pFrame == pFirstFrame) { pFirstFrame = NULL; } } delete [] tmp_desc; delete [] tmp_my_desc; delete [] tmp_lang; delete [] tmp_my_lang; // get the next frame until it wraps around } while ((pFrame = myTag.Find(frameList[ii].id)) != pFirstFrame); if (strlen(ID3_GetString(myFrame, ID3FN_TEXT)) > 0) { myTag.AttachFrame(myFrame); } break; } case ID3FID_WWWAUDIOFILE: case ID3FID_WWWARTIST: case ID3FID_WWWAUDIOSOURCE: case ID3FID_WWWCOMMERCIALINFO: case ID3FID_WWWCOPYRIGHT: case ID3FID_WWWPUBLISHER: case ID3FID_WWWPAYMENT: case ID3FID_WWWRADIOPAGE: { if (pFrame != NULL) { char *sURL = ID3_GetString(pFrame, ID3FN_URL); if (strcmp(frameList[ii].data, sURL) == 0) myTag.RemoveFrame(pFrame); } if (strlen(frameList[ii].data) > 0) { myFrame->Field(ID3FN_URL) = frameList[ii].data; myTag.AttachFrame(myFrame); } break; } case ID3FID_WWWUSER: { char *sURL = ID3_GetString(myFrame, ID3FN_URL), *sDesc = ID3_GetString(myFrame, ID3FN_DESCRIPTION); std::cout << "(" << sDesc << "): " << sURL << std::endl; delete [] sURL; delete [] sDesc; break; } case ID3FID_INVOLVEDPEOPLE: { // This isn't the right way to do it---will only get first person size_t nItems = myFrame->Field(ID3FN_TEXT).GetNumTextItems(); for (size_t nIndex = 1; nIndex <= nItems; nIndex++) { char *sPeople = ID3_GetString(myFrame, ID3FN_TEXT, nIndex); std::cout << sPeople; delete [] sPeople; if (nIndex < nItems) { std::cout << ", "; } } std::cout << std::endl; break; } case ID3FID_PICTURE: { myFrame->Field(ID3FN_DATA).FromFile(frameList[ii].data); myTag.AttachFrame(myFrame); break; } case ID3FID_GENERALOBJECT: { char *sMimeType = ID3_GetString(myFrame, ID3FN_TEXT), *sDesc = ID3_GetString(myFrame, ID3FN_DESCRIPTION), *sFileName = ID3_GetString(myFrame, ID3FN_FILENAME); size_t nDataSize = myFrame->Field(ID3FN_DATA).Size(); std::cout << "(" << sDesc << ")[" << sFileName << "]: " << sMimeType << ", " << nDataSize << " bytes" << std::endl; delete [] sMimeType; delete [] sDesc; delete [] sFileName; break; } case ID3FID_UNIQUEFILEID: { if (pFrame != NULL) { char *sOwner = ID3_GetString(pFrame, ID3FN_TEXT); size_t nDataSize = pFrame->Field(ID3FN_DATA).Size(); std::cout << sOwner << ", " << nDataSize << " bytes" << std::endl; delete [] sOwner; } break; } case ID3FID_PLAYCOUNTER: { if (pFrame != NULL) { size_t nCounter = pFrame->Field(ID3FN_COUNTER).Get(); std::cout << nCounter << std::endl; } break; } case ID3FID_POPULARIMETER: { if (pFrame != NULL) { char *sEmail = ID3_GetString(pFrame, ID3FN_EMAIL); size_t nCounter = pFrame->Field(ID3FN_COUNTER).Get(), nRating = pFrame->Field(ID3FN_RATING).Get(); std::cout << sEmail << ", counter=" << nCounter << " rating=" << nRating; delete [] sEmail; } break; } case ID3FID_CRYPTOREG: case ID3FID_GROUPINGREG: { char *sOwner = ID3_GetString(myFrame, ID3FN_OWNER); size_t nSymbol = myFrame->Field(ID3FN_ID).Get(), nDataSize = myFrame->Field(ID3FN_DATA).Size(); std::cout << "(" << nSymbol << "): " << sOwner << ", " << nDataSize << " bytes"; break; } case ID3FID_AUDIOCRYPTO: case ID3FID_EQUALIZATION: case ID3FID_EVENTTIMING: case ID3FID_CDID: case ID3FID_MPEGLOOKUP: case ID3FID_OWNERSHIP: case ID3FID_PRIVATE: case ID3FID_POSITIONSYNC: case ID3FID_BUFFERSIZE: case ID3FID_VOLUMEADJ: case ID3FID_REVERB: case ID3FID_SYNCEDLYRICS: case ID3FID_SYNCEDTEMPO: case ID3FID_METACRYPTO: { std::cout << " (unimplemented)" << std::endl; break; } default: { std::cout << " frame" << std::endl; break; } } } // steping thru frames luint nTags = myTag.Update(UpdFlags); /* update file with old mode */ if (chmod(argv[nIndex], filestat.st_mode)) { std::cerr << "Couldn't reset permissions on '" << argv[nIndex] << "'\n"; } } return 0; }