![]() |
Mixxx
|
00001 #include "audiotagger.h" 00002 00003 #include <QtDebug> 00004 #include <taglib/tag.h> 00005 #include <taglib/id3v2frame.h> 00006 00007 #include <taglib/id3v2frame.h> 00008 #include <taglib/id3v2header.h> 00009 #include <taglib/id3v1tag.h> 00010 #include <taglib/tmap.h> 00011 #include <taglib/tstringlist.h> 00012 00013 #include <taglib/vorbisfile.h> 00014 #include <taglib/wavpackfile.h> 00015 #include <taglib/mpegfile.h> 00016 #include <taglib/mp4file.h> 00017 #include <taglib/oggfile.h> 00018 #include <taglib/flacfile.h> 00019 #include <taglib/aifffile.h> 00020 #include <taglib/rifffile.h> 00021 #include <taglib/wavfile.h> 00022 #include <taglib/textidentificationframe.h> 00023 00024 AudioTagger::AudioTagger (QString file) 00025 { 00026 m_artist = ""; 00027 m_title = ""; 00028 m_genre = ""; 00029 m_album = ""; 00030 m_year = ""; 00031 m_comment = ""; 00032 m_key = ""; 00033 m_bpm = ""; 00034 m_tracknumber = ""; 00035 00036 m_file = file; 00037 } 00038 00039 AudioTagger::~AudioTagger ( ) 00040 { 00041 00042 } 00043 00044 00045 void AudioTagger::setArtist (QString artist ) 00046 { 00047 m_artist = artist; 00048 } 00049 00050 00051 00052 void AudioTagger::setTitle (QString title ) 00053 { 00054 m_title = title; 00055 } 00056 00057 00058 00059 void AudioTagger::setAlbum (QString album ) 00060 { 00061 m_album = album; 00062 } 00063 00064 00065 00066 void AudioTagger::setGenre (QString genre ) 00067 { 00068 m_genre = genre; 00069 } 00070 00071 00072 00073 void AudioTagger::setYear (QString year ) 00074 { 00075 m_year = year; 00076 } 00077 00078 00079 00080 void AudioTagger::setComment (QString comment ) 00081 { 00082 m_comment = comment; 00083 } 00084 00085 void AudioTagger::setKey (QString key ) 00086 { 00087 m_key = key; 00088 } 00089 00090 void AudioTagger::setBpm (QString bpm ) 00091 { 00092 m_bpm = bpm; 00093 } 00094 00095 void AudioTagger::setTracknumber (QString tracknumber ) 00096 { 00097 m_tracknumber = tracknumber; 00098 } 00099 bool AudioTagger::save () 00100 { 00101 TagLib::File* file = NULL; 00102 00103 if(m_file.endsWith(".mp3", Qt::CaseInsensitive)){ 00104 file = new TagLib::MPEG::File(m_file.toUtf8().constData()); 00105 //process special ID3 fields, APEv2 fiels, etc 00106 00107 //If the mp3 has no ID3v2 tag, we create a new one and add the TBPM and TKEY frame 00108 addID3v2Tag( ((TagLib::MPEG::File*) file)->ID3v2Tag(true) ); 00109 //If the mp3 has an APE tag, we update 00110 addAPETag( ((TagLib::MPEG::File*) file)->APETag(false) ); 00111 00112 } 00113 if(m_file.endsWith(".m4a", Qt::CaseInsensitive)){ 00114 file = new TagLib::MP4::File(m_file.toUtf8().constData()); 00115 //process special ID3 fields, APEv2 fiels, etc 00116 processMP4Tag(((TagLib::MP4::File*) file)->tag()); 00117 00118 } 00119 if(m_file.endsWith(".ogg", Qt::CaseInsensitive)){ 00120 file = new TagLib::Ogg::Vorbis::File(m_file.toUtf8().constData()); 00121 //process special ID3 fields, APEv2 fiels, etc 00122 addXiphComment( ((TagLib::Ogg::Vorbis::File*) file)->tag() ); 00123 00124 } 00125 if(m_file.endsWith(".wav", Qt::CaseInsensitive)){ 00126 file = new TagLib::RIFF::WAV::File(m_file.toUtf8().constData()); 00127 //If the flac has no ID3v2 tag, we create a new one and add the TBPM and TKEY frame 00128 addID3v2Tag( ((TagLib::RIFF::WAV::File*) file)->tag() ); 00129 00130 } 00131 if(m_file.endsWith(".flac", Qt::CaseInsensitive)){ 00132 file = new TagLib::FLAC::File(m_file.toUtf8().constData()); 00133 00134 //If the flac has no ID3v2 tag, we create a new one and add the TBPM and TKEY frame 00135 addID3v2Tag( ((TagLib::FLAC::File*) file)->ID3v2Tag(true) ); 00136 //If the flac has no APE tag, we create a new one and add the TBPM and TKEY frame 00137 addXiphComment( ((TagLib::FLAC::File*) file)->xiphComment (true) ); 00138 00139 } 00140 if(m_file.endsWith(".aif", Qt::CaseInsensitive) || m_file.endsWith(".aiff", Qt::CaseInsensitive)){ 00141 file = new TagLib::RIFF::AIFF::File(m_file.toUtf8().constData()); 00142 //If the flac has no ID3v2 tag, we create a new one and add the TBPM and TKEY frame 00143 addID3v2Tag( ((TagLib::RIFF::AIFF::File*) file)->tag() ); 00144 00145 } 00146 00147 //process standard tags 00148 if(file){ 00149 TagLib::Tag *tag = file->tag(); 00150 if (tag) 00151 { 00152 tag->setArtist(m_artist.toStdString()); 00153 tag->setTitle(m_title.toStdString()); 00154 tag->setAlbum(m_album.toStdString()); 00155 tag->setGenre(m_genre.toStdString()); 00156 tag->setComment(m_comment.toStdString()); 00157 uint year = m_year.toUInt(); 00158 if(year > 0) 00159 tag->setYear(year); 00160 uint tracknumber = m_tracknumber.toUInt(); 00161 if(tracknumber > 0) 00162 tag->setTrack(tracknumber); 00163 00164 } 00165 //write audio tags to file 00166 int success = file->save(); 00167 if (success) { 00168 qDebug() << "Successfully updated metadata of track " << m_file; 00169 } else { 00170 qDebug() << "Could not update metadata of track " << m_file; 00171 } 00172 //delete file and return 00173 delete file; 00174 return success; 00175 } 00176 else{ 00177 return false; 00178 } 00179 00180 00181 } 00182 void AudioTagger::addID3v2Tag(TagLib::ID3v2::Tag* id3v2) 00183 { 00184 if(!id3v2) return; 00185 00186 TagLib::ID3v2::FrameList bpmFrame = id3v2->frameListMap()["TBPM"]; 00187 if (!bpmFrame.isEmpty()) 00188 { 00189 bpmFrame.front()->setText(m_bpm.toStdString()); 00190 00191 } 00192 else 00193 { 00194 /* 00195 * add new frame TextIdentificationFrame which is responsible for TKEY and TBPM 00196 * see http://developer.kde.org/~wheeler/taglib/api/classTagLib_1_1ID3v2_1_1TextIdentificationFrame.html 00197 */ 00198 00199 TagLib::ID3v2::TextIdentificationFrame* newFrame = new TagLib::ID3v2::TextIdentificationFrame("TBPM", TagLib::String::Latin1); 00200 00201 newFrame->setText(m_bpm.toStdString()); 00202 id3v2->addFrame(newFrame); 00203 00204 } 00205 00206 TagLib::ID3v2::FrameList keyFrame = id3v2->frameListMap()["TKEY"]; 00207 if (!keyFrame.isEmpty()) 00208 { 00209 keyFrame.front()->setText(m_key.toStdString()); 00210 00211 } 00212 else 00213 { 00214 //add new frame 00215 TagLib::ID3v2::TextIdentificationFrame* newFrame = new TagLib::ID3v2::TextIdentificationFrame("TKEY", TagLib::String::Latin1); 00216 00217 newFrame->setText(m_key.toStdString()); 00218 id3v2->addFrame(newFrame); 00219 00220 } 00221 00222 } 00223 void AudioTagger::addAPETag(TagLib::APE::Tag* ape) 00224 { 00225 if(!ape) return; 00226 /* 00227 * Adds to the item specified by key the data value. 00228 * If replace is true, then all of the other values on the same key will be removed first. 00229 */ 00230 ape->addValue("BPM",m_bpm.toStdString(), true); 00231 ape->addValue("BPM",m_bpm.toStdString(), true); 00232 00233 00234 } 00235 void AudioTagger::addXiphComment(TagLib::Ogg::XiphComment* xiph) 00236 { 00237 if(!xiph) return; 00238 00239 // Some tools use "BPM" so check for that. 00240 00241 /* Taglib does not support the update of Vorbis comments. 00242 * thus, we have to reomve the old comment and add the new one 00243 */ 00244 xiph->removeField("BPM"); 00245 xiph->addField("BPM", m_bpm.toStdString()); 00246 00247 xiph->removeField("TEMPO"); 00248 xiph->addField("TEMPO", m_bpm.toStdString()); 00249 00250 xiph->removeField("INITIALKEY"); 00251 xiph->addField("INITIALKEY", m_key.toStdString()); 00252 xiph->removeField("KEY"); 00253 xiph->addField("KEY", m_key.toStdString()); 00254 00255 } 00256 void AudioTagger::processMP4Tag(TagLib::MP4::Tag* mp4) 00257 { 00258 //TODO 00259 00260 } 00261 00262