/* LPCTSTR means const char * */ size_t RemoveFrame(ID3_Tag& pTag, ID3_FrameID fID, LPCTSTR sDescription) { size_t nCount = 0; const ID3_Frame * frame = NULL; do { if (!sDescription) { cerr << "*** description is null" << endl; frame = pTag.Find(fID); } else { cerr << "*** description is \"" << sDescription << "\"" << endl; frame = pTag.Find(fID, ID3FN_DESCRIPTION, sDescription); } if (frame) { ID3_Field* fld = frame->GetField(ID3FN_TEXT); String text(fld->GetRawText(), fld->Size()); cerr << "*** delete frame with text \"" << text << "\"" << endl; /* pTag is an ID3_Tag */ delete pTag.RemoveFrame(frame); nCount++; } } while (frame != NULL); return nCount; }
void Genre_addGenre(ID3_Tag & id3, const char * genre) { ID3_Frame* frame = NULL; if (genre) { ID3_RemoveGenres(&id3); if (NULL == id3.Find(ID3FID_CONTENTTYPE)) { frame = new ID3_Frame(ID3FID_CONTENTTYPE); if (NULL != frame) { // int g = Genre_getInt(genre); // char sGenre[100]; // if (g > 0) { // sprintf(sGenre, "(%d)", g); // } else { // sprintf(sGenre, "%s", genre); // } frame->GetField(ID3FN_TEXT)->Set(genre); id3.AttachFrame(frame); } } } return; }
int main(int argc, char ** argv) { if (argc != 2) { cout << "usage: " << argv[0] << " output.mp3" << endl; return 1; } const char * filename = argv[1]; ID3_Tag tag; tag.Link(filename); AddTextFrame(tag, ID3FID_TITLE, "Dummy Title"); AddTextFrame(tag, ID3FID_LEADARTIST, "Dummy Artist"); AddTextFrame(tag, ID3FID_ALBUM, "Dummy Album"); AddTextFrame(tag, ID3FID_TRACKNUM, "1/10"); AddTextFrame(tag, ID3FID_YEAR, "2000"); AddTextFrame(tag, ID3FID_COMMENT, "Dummy Comment"); AddTextFrame(tag, ID3FID_COMMENT, "Dummy Comment 2"); AddTextFrame(tag, ID3FID_CONTENTTYPE, "Pop"); ID3_Frame userFrame(ID3FID_USERTEXT); userFrame.Field(ID3FN_DESCRIPTION).Set("MusicBrainz Album Id"); userFrame.Field(ID3FN_TEXT).Set("992dc19a-5631-40f5-b252-fbfedbc328a9"); tag.AddFrame(userFrame); tag.Update(); return 0; }
int main( unsigned int argc, char * const argv[]) { int ulFlag = ID3TT_ID3; ID3D_INIT_DOUT(); gengetopt_args_info args; if (cmdline_parser(argc, argv, &args) != 0) { exit(1); } #if defined ID3_ENABLE_DEBUG if (args.warning_flag) { ID3D_INIT_WARNING(); ID3D_WARNING ( "warnings turned on" ); } if (args.notice_flag) { ID3D_INIT_NOTICE(); ID3D_NOTICE ( "notices turned on" ); } #endif if (args.v1tag_flag) { ulFlag = ID3TT_ID3V1; } if (args.v2tag_flag) { ulFlag = ID3TT_ID3V2; } if (args.inputs_num != 2) { cerr << "Usage: id3cp [OPTIONS] SOURCE DEST" << endl; exit(1); } const char *source = args.inputs[0], *dest = args.inputs[1]; ID3_Tag myTag; cout << "Parsing " << source << ": "; myTag.Clear(); myTag.Link(source, ID3TT_ALL); cout << "done. Copying to " << dest << ": "; myTag.Link(dest, ID3TT_NONE); myTag.Update(ulFlag); cout << "done" << endl; return 0; }
void StripTags(char *file) { ID3_Tag myTag; myTag.Link(file); myTag.Strip(); return; }
int main( int argc, char *argv[]) { ID3D_INIT_DOUT(); ID3D_INIT_WARNING(); ID3D_INIT_NOTICE(); ID3_Tag tag; ID3_Frame frame; tag.Link("test-230-compressed.tag"); tag.Strip(ID3TT_ALL); tag.Clear(); frame.SetID(ID3FID_USERTEXT); frame.GetField(ID3FN_DESCRIPTION)->Set("compression example"); frame.GetField(ID3FN_TEXT)->Set("This sample user text frame came from an ID3v2-3.0 tag. The frame has the 'compression' bit set in it's frame header. This is the new method for compressing frames, which supercedes the 2.01 Compressed Data Metaframe."); frame.SetCompression(true); tag.AddFrame(frame); tag.SetPadding(false); tag.SetUnsync(false); tag.Update(ID3TT_ID3V2); return 0; }
int main( int argc, char ** argv ) { ID3_Tag tag; tag.Link( argv[1] ); AddTextFrame(tag, ID3FID_TITLE, "Dummy Title"); AddTextFrame(tag, ID3FID_LEADARTIST, "Dummy Artist"); AddTextFrame(tag, ID3FID_ALBUM, "Dummy Album"); AddTextFrame(tag, ID3FID_TRACKNUM, "1/10"); AddTextFrame(tag, ID3FID_YEAR, "2000"); AddTextFrame(tag, ID3FID_COMMENT, "Dummy Comment"); AddTextFrame(tag, ID3FID_COMMENT, "Dummy Comment 2"); AddTextFrame(tag, ID3FID_CONTENTTYPE, "Pop"); tag.Update(); return 0; }
bool DsdiffFileReader::readChunk_ID3(dsf2flac_uint64 chunkStart) { // read the header so that we are certain we are in the correct place. dsf2flac_int8 ident[5]; ident[4]='\0'; if (!readChunkHeader(ident,chunkStart)) return false; // check the ident if ( !checkIdent(ident,const_cast<dsf2flac_int8*>("ID3 ")) ) { errorMsg = "dsdiffFileReader::readChunk_ID3:chunk ident error"; return false; } // read the first ID3_TAGHEADERSIZE bytes of the metadata (which should be the header). dsf2flac_uint8 id3header[ID3_TAGHEADERSIZE]; if (file.read_uint8(id3header,ID3_TAGHEADERSIZE)) { return false; } // check this is actually an id3 header dsf2flac_int32 id3tagLen; if ( (id3tagLen = ID3_Tag::IsV2Tag(id3header)) < 1 ) { return false; } // return to the start of the metadata if (file.seekg(-ID3_TAGHEADERSIZE,std::ios_base::cur)) { file.clear(); return false; } // read the full id3 data dsf2flac_uint8* id3tag = new dsf2flac_uint8[ id3tagLen ]; if (file.read_uint8(id3tag,id3tagLen)) { return false; } ID3_Tag t; t.Parse(id3tag,id3tagLen); tags.push_back(t); delete[] id3tag; return true; }
// returns buffer len; caller frees int Tags::ExportID3(char **buffer, bool *endOfFile) { #ifdef USE_ID3LIB ID3_Tag tag; ID3_AddTitle(&tag, (const char *)mTitle); ID3_AddArtist(&tag, (const char *)mArtist); ID3_AddAlbum(&tag, (const char *)mAlbum); if (mTrackNum >=0 && mTrackNum<=255) ID3_AddTrack(&tag, (uchar)mTrackNum); ID3_AddGenre(&tag, mGenre); ID3_AddComment(&tag, (const char *)mComments, STR_V1_COMMENT_DESC); ID3_AddYear(&tag, (const char *)mYear); if (mID3V2) { int tagSize = tag.Size(); *buffer = new char[tagSize]; tag.Render((uchar *)*buffer, ID3TT_ID3V2); *endOfFile = false; return tagSize; } else { *buffer = new char[128]; for(int i=0; i<128; i++) (*buffer)[i] = 0; tag.Render((uchar *)*buffer, ID3TT_ID3V1); *endOfFile = true; return 128; } #else *buffer = new char[0]; *endOfFile = true; return 0; #endif // USE_ID3LIB }
void ListTag(int argc, char *argv[], int optind) { bool id3v1_tag = false; bool id3v2_tag = false; int ret = 0; for (int nIndex = optind; nIndex < argc; nIndex++) { ID3_Tag myTag; ret = PrintID3v1Tag(argv[nIndex]); if (ret == -1) { continue; } else if(ret == 0) { id3v1_tag = true; } myTag.Link(argv[nIndex], ID3TT_ID3V2); if(!PrintInformation(argv[nIndex],myTag)) id3v2_tag = true; if(!id3v1_tag && !id3v2_tag) std::cout << argv[nIndex] << ": No ID3 tag" << std::endl; else { if (!id3v1_tag) std::cout << argv[nIndex] << ": No ID3v1 tag" << std::endl; if (!id3v2_tag) std::cout << argv[nIndex] << ": No ID3v2 tag" << std::endl; } id3v1_tag = false; id3v2_tag = false; } return; }
int main( int argc, char *argv[]) { ID3_Tag tag; ID3_Frame frame; tag.Link("test-230-unicode.tag"); tag.Strip(ID3TT_ALL); tag.Clear(); frame.SetID(ID3FID_USERTEXT); frame.GetField(ID3FN_DESCRIPTION)->Set("example text frame"); frame.GetField(ID3FN_TEXT)->Set("This text and the description should be in Unicode."); frame.GetField(ID3FN_TEXTENC)->Set(ID3TE_UNICODE); tag.AddFrame(frame); tag.SetPadding(false); tag.SetUnsync(false); tag.Update(ID3TT_ID3V2); return 0; }
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; }
void AddTextFrame( ID3_Tag & tag, ID3_FrameID frameid, char * text ) { ID3_Frame frame(frameid); frame.Field(ID3FN_TEXT).Set(text); tag.AddFrame(frame); }
int main( int argc, char *argv[]) { ID3_Tag tag; ID3_Frame frame; if (argc == 2) { tag.Link(argv[1]); cerr << "removed " << RemoveFrame(tag, ID3FID_COMMENT, "") << " descriptionless comment frames" << endl; tag.Update(); } else { tag.Link("test-remove.tag"); tag.Strip(ID3TT_ALL); tag.Clear(); frame.SetID(ID3FID_TITLE); frame.GetField(ID3FN_TEXT)->Set("Test title"); tag.AddFrame(frame); frame.SetID(ID3FID_COMPOSER); frame.GetField(ID3FN_TEXT)->Set("Test composer"); tag.AddFrame(frame); frame.SetID(ID3FID_BAND); frame.GetField(ID3FN_TEXT)->Set("Test band"); tag.AddFrame(frame); frame.SetID(ID3FID_CONDUCTOR); frame.GetField(ID3FN_TEXT)->Set("Test conductor"); tag.AddFrame(frame); frame.SetID(ID3FID_COMMENT); frame.GetField(ID3FN_LANGUAGE)->Set("eng"); frame.GetField(ID3FN_TEXT)->Set("Test comment"); frame.GetField(ID3FN_DESCRIPTION)->Set("A Description"); tag.AddFrame(frame); frame.SetID(ID3FID_COMMENT); frame.GetField(ID3FN_LANGUAGE)->Set("eng"); frame.GetField(ID3FN_TEXT)->Set("Test comment 2"); frame.GetField(ID3FN_DESCRIPTION)->Set(""); tag.AddFrame(frame); frame.SetID(ID3FID_COMMENT); frame.GetField(ID3FN_LANGUAGE)->Set("eng"); frame.GetField(ID3FN_TEXT)->Set("ID3v1 comment text?"); frame.GetField(ID3FN_DESCRIPTION)->Set(STR_V1_COMMENT_DESC); tag.AddFrame(frame); tag.SetPadding(false); tag.Update(ID3TT_ID3V2); cerr << "removed " << ID3_RemoveArtists(&tag) << " artist frames" << endl; tag.Update(); cerr << "removed " << ID3_RemoveTitles(&tag) << " title frames" << endl; tag.Update(); cerr << "removed " << RemoveFrame(tag, ID3FID_COMMENT, "") << " descriptionless comment frames" << endl; tag.Update(); } return 0; }
int main(int argc, char* argv[]) { // Parse any command-line options. namespace po = boost::program_options; po::options_description desc("Allowed options"); desc.add_options() ("help", "show help") ("debug-httpd", po::value<bool>(&mp3d_debug_httpd), "show httpd debug output") ("root", po::value<std::string>(&mp3d_music_root), "root of file system mp3 tree") ("port", po::value<int>(&mp3d_port), "httpd port number") ; po::variables_map args; po::store(po::parse_command_line(argc, argv, desc), args); po::notify(args); if (args.count("help")) { std::cout << desc << std::endl; return 1; } // Index all the mp3s. Paths paths; find_mp3_files(mp3d_music_root, paths); std::cerr << ".mp3 files found: " << paths.size() << std::endl; int old_percentage = -1; size_t id = 0; for (Paths::const_iterator it = paths.begin(); it != paths.end(); ++it) { Mp3Info mp3; mp3.filename = (*it).string(); const ID3_Tag tag(mp3.filename.c_str()); ID3_Tag::ConstIterator* it = tag.CreateIterator(); for (size_t i = 0; i < tag.NumFrames(); ++i) { const ID3_Frame* frame = it->GetNext(); if (frame != 0) { std::string* dst; switch (frame->GetID()) { case ID3FID_ALBUM: dst = &mp3.album; break; case ID3FID_LEADARTIST: dst = &mp3.artist; break; case ID3FID_TITLE: dst = &mp3.title; break; default: continue; } char* text = ID3_GetString(frame, ID3FN_TEXT); dst->assign(text); ID3_FreeString(text); } } // FIXME: maybe a hash, to enable bookmarks? mp3.id = id++; all_mp3s.push_back(mp3); // Show progress. Not really useful when we're not debugging. // FIXME: start the web server straight away, and say "Indexing..." there. const int new_percentage = (100*all_mp3s.size())/paths.size(); if (new_percentage != old_percentage) { std::cout << "\rScanned: " << new_percentage << "%" << std::flush; old_percentage = new_percentage; } } std::cout << "\r.mp3 files scanned: " << all_mp3s.size() << std::endl; // Set up the static files we need to serve. read_static_file("/static/add.png", "/usr/share/icons/gnome/16x16/actions/gtk-add.png"); read_static_file("/static/play.png", "/usr/share/icons/gnome/16x16/actions/gtk-media-play-ltr.png"); read_static_file("/static/remove.png", "/usr/share/icons/gnome/16x16/actions/gtk-remove.png"); static_file_map["/static/site.css"] = make_css(); // Start the mp3 player thread. boost::thread mp3_player_thread(mp3_play_loop); // Start the HTTP server. std::cerr << "Starting HTTP server on port " << mp3d_port << "..." << std::endl; const int mhd_flags = MHD_USE_SELECT_INTERNALLY; MHD_Daemon* daemon = MHD_start_daemon(mhd_flags, mp3d_port, 0, 0, &handle_request, 0, MHD_OPTION_END); if (daemon == 0) { fail("MHD_start_daemon failed!"); } getchar(); // Wait for the user to hit enter. MHD_stop_daemon(daemon); //mp3_player_thread.join(); return 0; }
void PrintInformation(const ID3_Tag &myTag) { ID3_Tag::ConstIterator* iter = myTag.CreateIterator(); const ID3_Frame* frame = NULL; while (NULL != (frame = iter->GetNext())) { const char* desc = frame->GetDescription(); if (!desc) desc = ""; cout << "=== " << frame->GetTextID() << " (" << desc << "): "; ID3_FrameID eFrameID = frame->GetID(); switch (eFrameID) { 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_TRACKNUM: case ID3FID_RECORDINGDATES: case ID3FID_NETRADIOSTATION: case ID3FID_NETRADIOOWNER: case ID3FID_SIZE: case ID3FID_ISRC: case ID3FID_ENCODERSETTINGS: case ID3FID_YEAR: { char *sText = ID3_GetString(frame, ID3FN_TEXT); cout << sText << endl; delete [] sText; break; } case ID3FID_USERTEXT: { char *sText = ID3_GetString(frame, ID3FN_TEXT), *sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION); cout << "(" << sDesc << "): " << sText << endl; delete [] sText; delete [] sDesc; break; } case ID3FID_COMMENT: case ID3FID_UNSYNCEDLYRICS: { char *sText = ID3_GetString(frame, ID3FN_TEXT), *sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION), *sLang = ID3_GetString(frame, ID3FN_LANGUAGE); cout << "(" << sDesc << ")[" << sLang << "]: " << sText << endl; delete [] sText; delete [] sDesc; delete [] sLang; 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: { char *sURL = ID3_GetString(frame, ID3FN_URL); cout << sURL << endl; delete [] sURL; break; } case ID3FID_WWWUSER: { char *sURL = ID3_GetString(frame, ID3FN_URL), *sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION); cout << "(" << sDesc << "): " << sURL << endl; delete [] sURL; delete [] sDesc; break; } case ID3FID_INVOLVEDPEOPLE: { size_t nItems = frame->GetField(ID3FN_TEXT)->GetNumTextItems(); for (size_t nIndex = 0; nIndex < nItems; nIndex++) { char *sPeople = ID3_GetString(frame, ID3FN_TEXT, nIndex); cout << sPeople; delete [] sPeople; if (nIndex + 1 < nItems) { cout << ", "; } } cout << endl; break; } case ID3FID_PICTURE: { char *sMimeType = ID3_GetString(frame, ID3FN_MIMETYPE), *sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION), *sFormat = ID3_GetString(frame, ID3FN_IMAGEFORMAT); size_t nPicType = frame->GetField(ID3FN_PICTURETYPE)->Get(), nDataSize = frame->GetField(ID3FN_DATA)->Size(); cout << "(" << sDesc << ")[" << sFormat << ", " << nPicType << "]: " << sMimeType << ", " << nDataSize << " bytes" << endl; delete [] sMimeType; delete [] sDesc; delete [] sFormat; break; } case ID3FID_GENERALOBJECT: { char *sMimeType = ID3_GetString(frame, ID3FN_MIMETYPE), *sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION), *sFileName = ID3_GetString(frame, ID3FN_FILENAME); size_t nDataSize = frame->GetField(ID3FN_DATA)->Size(); cout << "(" << sDesc << ")[" << sFileName << "]: " << sMimeType << ", " << nDataSize << " bytes" << endl; delete [] sMimeType; delete [] sDesc; delete [] sFileName; break; } case ID3FID_UNIQUEFILEID: { char *sOwner = ID3_GetString(frame, ID3FN_OWNER); size_t nDataSize = frame->GetField(ID3FN_DATA)->Size(); cout << sOwner << ", " << nDataSize << " bytes" << endl; delete [] sOwner; break; } case ID3FID_PLAYCOUNTER: { size_t nCounter = frame->GetField(ID3FN_COUNTER)->Get(); cout << nCounter << endl; break; } case ID3FID_POPULARIMETER: { char *sEmail = ID3_GetString(frame, ID3FN_EMAIL); size_t nCounter = frame->GetField(ID3FN_COUNTER)->Get(), nRating = frame->GetField(ID3FN_RATING)->Get(); cout << sEmail << ", counter=" << nCounter << " rating=" << nRating << endl; delete [] sEmail; break; } case ID3FID_CRYPTOREG: case ID3FID_GROUPINGREG: { char *sOwner = ID3_GetString(frame, ID3FN_OWNER); size_t nSymbol = frame->GetField(ID3FN_ID)->Get(), nDataSize = frame->GetField(ID3FN_DATA)->Size(); cout << "(" << nSymbol << "): " << sOwner << ", " << nDataSize << " bytes" << endl; break; } case ID3FID_SYNCEDLYRICS: { char *sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION), *sLang = ID3_GetString(frame, ID3FN_LANGUAGE); size_t nTimestamp = frame->GetField(ID3FN_TIMESTAMPFORMAT)->Get(), nRating = frame->GetField(ID3FN_CONTENTTYPE)->Get(); const char* format = (2 == nTimestamp) ? "ms" : "frames"; cout << "(" << sDesc << ")[" << sLang << "]: "; switch (nRating) { case ID3CT_OTHER: cout << "Other"; break; case ID3CT_LYRICS: cout << "Lyrics"; break; case ID3CT_TEXTTRANSCRIPTION: cout << "Text transcription"; break; case ID3CT_MOVEMENT: cout << "Movement/part name"; break; case ID3CT_EVENTS: cout << "Events"; break; case ID3CT_CHORD: cout << "Chord"; break; case ID3CT_TRIVIA: cout << "Trivia/'pop up' information"; break; } cout << endl; ID3_Field* fld = frame->GetField(ID3FN_DATA); if (fld) { ID3_MemoryReader mr(fld->GetRawBinary(), fld->BinSize()); while (!mr.atEnd()) { cout << io::readString(mr).c_str(); cout << " [" << io::readBENumber(mr, sizeof(uint32)) << " " << format << "] "; } } cout << endl; delete [] sDesc; delete [] sLang; 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_SYNCEDTEMPO: case ID3FID_METACRYPTO: { cout << " (unimplemented)" << endl; break; } default: { cout << " frame" << endl; break; } } } delete iter; }
int main( unsigned int argc, char * const argv[]) { ID3D_INIT_DOUT(); gengetopt_args_info args; if (cmdline_parser(argc, argv, &args) != 0) { exit(1); } #if defined ID3_ENABLE_DEBUG if (args.warning_flag) { ID3D_INIT_WARNING(); ID3D_WARNING ( "warnings turned on" ); } if (args.notice_flag) { ID3D_INIT_NOTICE(); ID3D_NOTICE ( "notices turned on" ); } #endif const char* filename = NULL; for (size_t i = 0; i < args.inputs_num; ++i) { filename = args.inputs[i]; ID3_Tag myTag; myTag.Link(filename, ID3TT_ALL); const Mp3_Headerinfo* mp3info; mp3info = myTag.GetMp3HeaderInfo(); cout << endl << "*** Tag information for " << filename << endl; if (!args.assign_given) { PrintInformation(myTag); } else { cout << "*** Testing assignment operator" << endl; ID3_Tag tmpTag(myTag); PrintInformation(tmpTag); } if (mp3info) { cout << "*** mp3 info\n"; switch (mp3info->version) { case MPEGVERSION_2_5: cout << "MPEG2.5/"; break; case MPEGVERSION_2: cout << "MPEG2/"; break; case MPEGVERSION_1: cout << "MPEG1/"; break; default: break; } switch (mp3info->layer) { case MPEGLAYER_III: cout << "layer III\n"; break; case MPEGLAYER_II: cout << "layer II\n"; break; case MPEGLAYER_I: cout << "layer I\n"; break; default: break; } cout << "Bitrate: " << mp3info->bitrate/1000 << "KBps\n"; cout << "Frequency: " << mp3info->frequency/1000 << "KHz\n"; } } return 0; }
int main( int argc, char *argv[]) { ID3D_INIT_DOUT(); ID3D_INIT_WARNING(); ID3D_INIT_NOTICE(); ID3_Tag tag; ID3_Frame frame; tag.Link("test-230-picture.tag"); tag.Strip(ID3TT_ALL); tag.Clear(); frame.SetID(ID3FID_TITLE); frame.GetField(ID3FN_TEXT)->Set("Aquarium"); tag.AddFrame(frame); frame.SetID(ID3FID_CONTENTGROUP); frame.GetField(ID3FN_TEXT)->Set("Short fraction of 'Carnival of the Animals: A Grand Zoological Fantasy'"); tag.AddFrame(frame); frame.SetID(ID3FID_COMPOSER); frame.GetField(ID3FN_TEXT)->Set("Camille Saint-Saëns"); tag.AddFrame(frame); frame.SetID(ID3FID_BAND); frame.GetField(ID3FN_TEXT)->Set("Slovakia Radio Symphony Orchestra"); tag.AddFrame(frame); frame.SetID(ID3FID_CONDUCTOR); frame.GetField(ID3FN_TEXT)->Set("Ondrej Lenárd"); tag.AddFrame(frame); frame.SetID(ID3FID_COPYRIGHT); frame.GetField(ID3FN_TEXT)->Set("1996 HNH international Ltd."); tag.AddFrame(frame); frame.SetID(ID3FID_CONTENTTYPE); frame.GetField(ID3FN_TEXT)->Set("(32)"); tag.AddFrame(frame); frame.SetID(ID3FID_INVOLVEDPEOPLE); frame.GetField(ID3FN_TEXT)->Add("Producer"); frame.GetField(ID3FN_TEXT)->Add("Martin Sauer"); frame.GetField(ID3FN_TEXT)->Add("Piano"); frame.GetField(ID3FN_TEXT)->Add("Peter Toperczer"); tag.AddFrame(frame); frame.SetID(ID3FID_PICTURE); frame.GetField(ID3FN_MIMETYPE)->Set("image/jpeg"); frame.GetField(ID3FN_PICTURETYPE)->Set(11); frame.GetField(ID3FN_DESCRIPTION)->Set("B/W picture of Saint-Saëns"); frame.GetField(ID3FN_DATA)->FromFile("composer.jpg"); tag.AddFrame(frame); tag.SetPadding(false); tag.SetUnsync(true); tag.Update(ID3TT_ID3V2); return 0; }
int main(int argc, char * const argv[]) { int ulFlag = ID3TT_ID3; ID3D_INIT_DOUT(); gengetopt_args_info args; if (cmdline_parser(argc, argv, &args) != 0) { exit(1); } #if defined ID3_ENABLE_DEBUG if (args.warning_flag) { ID3D_INIT_WARNING(); ID3D_WARNING ( "warnings turned on" ); } if (args.notice_flag) { ID3D_INIT_NOTICE(); ID3D_NOTICE ( "notices turned on" ); } #endif if (args.v1tag_flag) { ulFlag = ID3TT_ID3V1; } if (args.v2tag_flag) { ulFlag = ID3TT_ID3V2; } const char *sArtist = "", *sAlbum = "", *sTitle = "", *sComment = "", *sYear = "", *sDesc = ""; unsigned short nYear = 0, nTrack = 0, nTotal = 0, nGenre = 0; if (args.artist_given) { sArtist = args.artist_arg; cout << "+++ Artist = " << sArtist << endl; } if (args.album_given) { sAlbum = args.album_arg; cout << "+++ Album = " << sAlbum << endl; } if (args.song_given) { sTitle = args.song_arg; cout << "+++ Song = " << sTitle << endl; } if (args.year_given) { sYear = args.year_arg; nYear = ::strtol(sYear, NULL, 10); cout << "+++ Year = " << nYear << endl; } if (args.comment_given) { sComment = args.comment_arg; cout << "+++ Comment = " << sComment << endl; if (args.desc_given) { sDesc = args.desc_arg; cout << "+++ Comment Description" << endl; cout << " = " << sDesc << endl; } else { sDesc = ""; } } if (args.genre_given && args.genre_arg > 0 && args.genre_arg < 0xFF) { nGenre = args.genre_arg; cout << "+++ Genre = " << args.genre_arg << endl; } if (args.track_given) { nTrack = ::strtol(args.track_arg, NULL, 10); cout << "+++ Track = " << nTrack << endl; } if (args.total_given) { nTotal = ::strtol(args.total_arg, NULL, 10); cout << "+++ Total = " << nTotal << endl; } const char* filename = NULL; for (size_t i = 0; i < args.inputs_num; ++i) { filename = args.inputs[i]; ID3_Tag myTag; cout << "Tagging " << filename << ": "; myTag.Link(filename); cout << "attempting "; DisplayTags(cout, ulFlag); if (args.artist_given) { ID3_AddArtist(&myTag, sArtist, true); } if (args.album_given) { ID3_AddAlbum(&myTag, sAlbum, true); } if (args.song_given) { ID3_AddTitle(&myTag, sTitle, true); } if (args.year_given) { ID3_AddYear(&myTag, sYear, true); } if (args.comment_given) { ID3_AddComment(&myTag, sComment, sDesc, true); } if (args.genre_given) { ID3_AddGenre(&myTag, nGenre, true); } if (args.track_given) { ID3_AddTrack(&myTag, nTrack, nTotal, true); } luint nTags = myTag.Update(ulFlag); cout << ", tagged "; DisplayTags(cout, nTags); cout << endl; } return 0; }
//*************************************************************************** bool Kwave::MP3Decoder::parseID3Tags(ID3_Tag &tag) { if (tag.NumFrames() < 1) return true; // no tags, nothing to do QDate creation_date; QTime creation_time; int year = -1; int month = -1; int day = -1; ID3_Tag::Iterator *it = tag.CreateIterator(); ID3_Frame *frame = 0; Kwave::FileInfo info(metaData()); while (it && (frame = it->GetNext())) { const ID3_FrameID id = frame->GetID(); const Kwave::FileProperty property = m_property_map.property(id); const ID3_PropertyMap::Encoding encoding = m_property_map.encoding(id); switch (encoding) { case ID3_PropertyMap::ENC_TEXT_PARTINSET: { QString s = parseId3Frame2String(frame); int cd = 0; int cds = 0; if (s.contains(QLatin1Char('/'))) { int i = s.indexOf(QLatin1Char('/')); cd = s.left(i).toInt(); cds = s.mid(i + 1).toInt(); } else { cd = s.toInt(); } if (cd > 0) info.set(Kwave::INF_CD , QVariant(cd)); if (cds > 0) info.set(Kwave::INF_CDS, QVariant(cds)); break; } case ID3_PropertyMap::ENC_TRACK_NUM: { QString s = parseId3Frame2String(frame); int track = 0; int tracks = 0; if (s.contains(QLatin1Char('/'))) { int i = s.indexOf(QLatin1Char('/')); track = s.left(i).toInt(); tracks = s.mid(i + 1).toInt(); } else { track = s.toInt(); } if (track > 0) info.set(Kwave::INF_TRACK , QVariant(track)); if (tracks > 0) info.set(Kwave::INF_TRACKS, QVariant(tracks)); break; } case ID3_PropertyMap::ENC_TERMS_OF_USE: // the same as ENC_COMMENT, but without "Description" /* FALLTHROUGH */ case ID3_PropertyMap::ENC_COMMENT: { QString s = parseId3Frame2String(frame); // optionally prepend language char *lang = ID3_GetString(frame, ID3FN_LANGUAGE); if (lang) { s = _("[") + _(lang) + _("] ") + s; ID3_FreeString(lang); } // append to already existing tag, separated by a slash if (info.contains(property)) s = info.get(property).toString() + _(" / ") + s; info.set(property, QVariant(s)); break; } case ID3_PropertyMap::ENC_GENRE_TYPE: { QString s = parseId3Frame2String(frame); int genre = Kwave::GenreType::fromID3(s); if (genre >= 0) s = Kwave::GenreType::name(genre, false); info.set(property, QVariant(s)); break; } case ID3_PropertyMap::ENC_LENGTH: { // length in ms -> convert this to samples QString s = parseId3Frame2String(frame); const double rate = info.rate(); bool ok = false; const double ms = s.toDouble(&ok) + 0.5; if (ok && (rate > 0)) { // NOTE: this overwrites the length found in the header! sample_index_t length = static_cast<sample_index_t>( (rate * ms) / 1000.0); info.setLength(length); } break; } case ID3_PropertyMap::ENC_TEXT_TIMESTAMP: { if (!creation_date.isValid()) { QString s = parseId3Frame2String(frame); switch (id) { case ID3FID_RECORDINGDATES: // should be a ISO 8601 timestamp or similar s = Kwave::string2date(s); if (s.length()) creation_date = QDate::fromString(s, Qt::ISODate); break; case ID3FID_DATE: { // DDMM unsigned int ddmm = s.toUInt(); day = ddmm / 100; month = ddmm % 100; break; } case ID3FID_YEAR: /* FALLTHROUGH */ case ID3FID_ORIGYEAR: // YYYY year = s.toUInt(); break; default: break; } } if (creation_time.isValid()) { switch (id) { case ID3FID_TIME: creation_time = QTime::fromString(_("hhmm")); break; default: break; } } break; } case ID3_PropertyMap::ENC_TEXT_SLASH: { // append to already existing tag, separated by a slash QString s = parseId3Frame2String(frame); if (info.contains(property)) s = info.get(property).toString() + _(" / ") + s; info.set(property, QVariant(s)); break; } case ID3_PropertyMap::ENC_TEXT_URL: /* FALLTHROUGH */ case ID3_PropertyMap::ENC_TEXT: info.set(property, QVariant(parseId3Frame2String(frame))); break; case ID3_PropertyMap::ENC_NONE: /* FALLTHROUGH */ default: { QString s = parseId3Frame2String(frame); qWarning("unsupported ID3 tag: %d, descr: '%s', text: '%s'", id, frame->GetDescription(), DBG(s)); break; } } } /* * try to build a valid creation date/time */ if (!creation_date.isValid()) { // no complete creation date - try to reassemble from found y/m/d creation_date = QDate(year, month, day); } if (creation_date.isValid() && creation_time.isValid()) { // full date + time QDateTime dt(creation_date, creation_time); info.set(Kwave::INF_CREATION_DATE, dt.toString( _("yyyy-MM-ddTHH:mm:ss"))); } else if (creation_date.isValid()) { // date without time info.set(Kwave::INF_CREATION_DATE, creation_date.toString( _("yyyy-MM-dd"))); } else if (year > 0) { // only year creation_date = QDate(year, 1, 1); info.set(Kwave::INF_CREATION_DATE, creation_date.toString(_("yyyy"))); } metaData().replace(Kwave::MetaDataList(info)); return true; }
int PrintInformation(char *sFileName, const ID3_Tag &myTag) { bool firstLine = true; const ID3_Frame * myFrame; ID3_Tag::ConstIterator *Iter=myTag.CreateIterator(); for (size_t nFrames = 0; nFrames < myTag.NumFrames(); nFrames++) { myFrame = Iter->GetNext(); if(firstLine) { std::cout << "id3v2 tag info for " << sFileName << ":" << std::endl; firstLine = false; } if (NULL != myFrame) { const char* desc = myFrame->GetDescription(); if (!desc) desc = ""; std::cout << myFrame->GetTextID() << " (" << desc << "): "; ID3_FrameID eFrameID = myFrame->GetID(); switch (eFrameID) { case ID3FID_ALBUM: case ID3FID_BPM: case ID3FID_COMPOSER: 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_TRACKNUM: case ID3FID_RECORDINGDATES: case ID3FID_NETRADIOSTATION: case ID3FID_NETRADIOOWNER: case ID3FID_SIZE: case ID3FID_ISRC: case ID3FID_ENCODERSETTINGS: case ID3FID_YEAR: { char *sText = ID3_GetString(myFrame, ID3FN_TEXT); std::cout << sText << std::endl; delete [] sText; break; } case ID3FID_CONTENTTYPE: { const char* genre_str; int genre_id = 255; char *sText = ID3_GetString(myFrame, ID3FN_TEXT); sscanf(sText, "(%d)", &genre_id); if (genre_id == 255) { genre_str = sText; genre_id = GetNumFromGenre(sText); } else genre_str = GetGenreFromNum(genre_id); std::cout << genre_str << " (" << genre_id << ")" << std::endl; delete [] sText; break; } case ID3FID_USERTEXT: { char *sText = ID3_GetString(myFrame, ID3FN_TEXT), *sDesc = ID3_GetString(myFrame, ID3FN_DESCRIPTION); std::cout << "(" << sDesc << "): " << sText << std::endl; delete [] sText; delete [] sDesc; break; } case ID3FID_TERMSOFUSE: { char *sText = ID3_GetString(myFrame, ID3FN_TEXT), *sLang = ID3_GetString(myFrame, ID3FN_LANGUAGE); std::cout << "[" << sLang << "]: " << sText << std::endl; delete [] sText; delete [] sLang; break; } case ID3FID_COMMENT: case ID3FID_UNSYNCEDLYRICS: { char *sText = ID3_GetString(myFrame, ID3FN_TEXT), *sDesc = ID3_GetString(myFrame, ID3FN_DESCRIPTION), *sLang = ID3_GetString(myFrame, ID3FN_LANGUAGE); std::cout << "(" << sDesc << ")[" << sLang << "]: " << sText << std::endl; delete [] sText; delete [] sDesc; delete [] sLang; 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: { char *sURL = ID3_GetString(myFrame, ID3FN_URL); std::cout << sURL << std::endl; delete [] sURL; 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: { char *sMimeType = ID3_GetString(myFrame, ID3FN_MIMETYPE), *sDesc = ID3_GetString(myFrame, ID3FN_DESCRIPTION), *sFormat = ID3_GetString(myFrame, ID3FN_IMAGEFORMAT); size_t nPicType = myFrame->Field(ID3FN_PICTURETYPE).Get(), nDataSize = myFrame->Field(ID3FN_DATA).Size(); std::cout << "(" << sDesc << ")[" << sFormat << ", " << nPicType << "]: " << sMimeType << ", " << nDataSize << " bytes" << std::endl; delete [] sMimeType; delete [] sDesc; delete [] sFormat; break; } case ID3FID_GENERALOBJECT: { char *sMimeType = ID3_GetString(myFrame, ID3FN_MIMETYPE), *sDesc = ID3_GetString(myFrame, ID3FN_DESCRIPTION), *sFileName = ID3_GetString(myFrame, ID3FN_FILENAME); size_t nDataSize = myFrame->GetField(ID3FN_DATA)->Size(); std::cout << "(" << sDesc << ")[" << sFileName << "]: " << sMimeType << ", " << nDataSize << " bytes" << std::endl; delete [] sMimeType; delete [] sDesc; delete [] sFileName; break; } case ID3FID_UNIQUEFILEID: { char *sOwner = ID3_GetString(myFrame, ID3FN_OWNER); size_t nDataSize = myFrame->Field(ID3FN_DATA).Size(); std::cout << sOwner << ", " << nDataSize << " bytes" << std::endl; delete [] sOwner; break; } case ID3FID_PLAYCOUNTER: { size_t nCounter = myFrame->Field(ID3FN_COUNTER).Get(); std::cout << nCounter << std::endl; break; } case ID3FID_POPULARIMETER: { char *sEmail = ID3_GetString(myFrame, ID3FN_EMAIL); size_t nCounter = myFrame->Field(ID3FN_COUNTER).Get(), nRating = myFrame->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; } } } } delete Iter; if(firstLine) return 1; return 0; }
//*************************************************************************** bool Kwave::MP3Decoder::open(QWidget *widget, QIODevice &src) { qDebug("MP3Decoder::open()"); metaData().clear(); Q_ASSERT(!m_source); if (m_source) qWarning("MP3Decoder::open(), already open !"); /* open the file in readonly mode with seek enabled */ if (src.isSequential()) return false; if (!src.open(QIODevice::ReadOnly)) { qWarning("unable to open source in read-only mode!"); return false; } /* read all available ID3 tags */ ID3_Tag tag; ID3_QIODeviceReader adapter(src); tag.Link(adapter, static_cast<flags_t>(ID3TT_ALL)); qDebug("NumFrames = %u", Kwave::toUint(tag.NumFrames())); /** @bug: id3lib crashes in this line on some MP3 files */ if (tag.GetSpec() != ID3V2_UNKNOWN) { qDebug("Size = %u", Kwave::toUint(tag.Size())); } qDebug("HasLyrics = %d", tag.HasLyrics()); qDebug("HasV1Tag = %d", tag.HasV1Tag()); qDebug("HasV2Tag = %d", tag.HasV2Tag()); m_prepended_bytes = tag.GetPrependedBytes(); m_appended_bytes = tag.GetAppendedBytes(); qDebug("prepended=%lu, appended=%lu", m_prepended_bytes, m_appended_bytes); const Mp3_Headerinfo *mp3hdr = tag.GetMp3HeaderInfo(); if (!mp3hdr) { Kwave::MessageBox::sorry(widget, i18n("The opened file is no MPEG file or it is damaged.\n" "No header information has been found.")); return false; } /* parse the MP3 header */ if (!parseMp3Header(*mp3hdr, widget)) return false; /* parse the ID3 tags */ if (!parseID3Tags(tag)) return false; /* accept the source */ m_source = &src; Kwave::FileInfo info(metaData()); info.set(Kwave::INF_MIMETYPE, _("audio/mpeg")); metaData().replace(Kwave::MetaDataList(info)); // allocate a transfer buffer with 128 kB if (m_buffer) free(m_buffer); m_buffer_size = (128 << 10); m_buffer = static_cast<unsigned char *>(malloc(m_buffer_size)); if (!m_buffer) return false; // out of memory :-( return true; }
int main( unsigned int argc, char * const argv[]) { flags_t ulFlag = ID3TT_ALL; gengetopt_args_info args; if (cmdline_parser(argc, argv, &args) != 0) { exit(1); } #if defined ID3_ENABLE_DEBUG if (args.warning_flag) { ID3D_INIT_WARNING(); ID3D_WARNING ( "warnings turned on" ); } if (args.notice_flag) { ID3D_INIT_NOTICE(); ID3D_NOTICE ( "notices turned on" ); } #endif if (args.v1tag_flag) { ulFlag = ID3TT_ID3V1; } if (args.v2tag_flag) { ulFlag = ID3TT_ID3V2; } const char* filename = NULL; for (size_t i = 0; i < args.inputs_num; ++i) { filename = args.inputs[i]; ID3_Tag myTag; if (args.strip_given) { cout << "Stripping "; } else { cout << "Converting "; } cout << filename << ": "; myTag.Clear(); myTag.Link(filename, ID3TT_ALL); myTag.SetPadding(args.padding_flag); cout << "attempting "; DisplayTags(cout, ulFlag); luint nTags; if (args.strip_flag) { nTags = myTag.Strip(ulFlag); cout << ", stripped "; } else { nTags = myTag.Update(ulFlag); cout << ", converted "; } DisplayTags(cout, nTags); cout << endl; } return 0; }