|
|
|
|
@@ -75,6 +75,8 @@
|
|
|
|
|
#include <taglib-extras/realmediafiletyperesolver.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static int id3v2Version=3; // Set to 4 to save ID3v2.4 and 3 for ID3v2.3
|
|
|
|
|
|
|
|
|
|
namespace Tags
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
@@ -384,11 +386,15 @@ static bool writeID3v2Tags(TagLib::ID3v2::Tag *tag, const Song &from, const Song
|
|
|
|
|
while (clearRva2Tag(tag, TagLib::String("track").upper()));
|
|
|
|
|
setTxxxTag(tag, "replaygain_track_gain", rgs.trackGain);
|
|
|
|
|
setTxxxTag(tag, "replaygain_track_peak", rgs.trackPeak);
|
|
|
|
|
setRva2Tag(tag, "track", rg.trackGain, rg.trackPeak);
|
|
|
|
|
if (id3v2Version>3) {
|
|
|
|
|
setRva2Tag(tag, "track", rg.trackGain, rg.trackPeak);
|
|
|
|
|
}
|
|
|
|
|
if (rg.albumMode) {
|
|
|
|
|
setTxxxTag(tag, "replaygain_album_gain", rgs.albumGain);
|
|
|
|
|
setTxxxTag(tag, "replaygain_album_peak", rgs.albumPeak);
|
|
|
|
|
setRva2Tag(tag, "album", rg.albumGain, rg.albumPeak);
|
|
|
|
|
if (id3v2Version>3) {
|
|
|
|
|
setRva2Tag(tag, "album", rg.albumGain, rg.albumPeak);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
changed=true;
|
|
|
|
|
}
|
|
|
|
|
@@ -938,6 +944,13 @@ static bool writeTags(const TagLib::FileRef fileref, const Song &from, const Son
|
|
|
|
|
|
|
|
|
|
static QMutex mutex;
|
|
|
|
|
|
|
|
|
|
void setID3V2Version(int v)
|
|
|
|
|
{
|
|
|
|
|
if (3==v || 4==v) {
|
|
|
|
|
id3v2Version=v;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Song read(const QString &fileName)
|
|
|
|
|
{
|
|
|
|
|
QMutexLocker locker(&mutex);
|
|
|
|
|
@@ -988,6 +1001,21 @@ QString readLyrics(const QString &fileName)
|
|
|
|
|
return lyrics;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Update update(const TagLib::FileRef fileref, const Song &from, const Song &to, const RgTags &rg, const QByteArray &img)
|
|
|
|
|
{
|
|
|
|
|
TagLib::MPEG::File *mpeg=dynamic_cast<TagLib::MPEG::File *>(fileref.file());
|
|
|
|
|
TagLib::ID3v1::Tag *v1=mpeg ? mpeg->ID3v1Tag(false) : 0;
|
|
|
|
|
bool haveV1=v1 && (!v1->title().isEmpty() || !v1->artist().isEmpty() || !v1->album().isEmpty());
|
|
|
|
|
|
|
|
|
|
if (writeTags(fileref, from, to, rg, img)) {
|
|
|
|
|
if (mpeg) {
|
|
|
|
|
return mpeg->save((haveV1 ? TagLib::MPEG::File::ID3v1 : 0)|TagLib::MPEG::File::ID3v2, true, id3v2Version) ? Update_Modified : Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
return fileref.file()->save() ? Update_Modified : Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
return Update_None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Update updateArtistAndTitle(const QString &fileName, const Song &song)
|
|
|
|
|
{
|
|
|
|
|
QMutexLocker locker(&mutex);
|
|
|
|
|
@@ -1006,8 +1034,8 @@ Update updateArtistAndTitle(const QString &fileName, const Song &song)
|
|
|
|
|
tag->setTitle(qString2TString(song.title));
|
|
|
|
|
tag->setArtist(qString2TString(song.artist));
|
|
|
|
|
|
|
|
|
|
if (mpeg && !haveV1) {
|
|
|
|
|
return mpeg->save(TagLib::MPEG::File::ID3v2) ? Update_Modified : Update_Failed;
|
|
|
|
|
if (mpeg) {
|
|
|
|
|
return mpeg->save((haveV1 ? TagLib::MPEG::File::ID3v1 : 0)|TagLib::MPEG::File::ID3v2, id3v2Version) ? Update_Modified : Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
return fileref.file()->save() ? Update_Modified : Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
@@ -1018,22 +1046,7 @@ Update update(const QString &fileName, const Song &from, const Song &to)
|
|
|
|
|
ensureFileTypeResolvers();
|
|
|
|
|
|
|
|
|
|
TagLib::FileRef fileref = getFileRef(fileName);
|
|
|
|
|
|
|
|
|
|
if (fileref.isNull()) {
|
|
|
|
|
return Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TagLib::MPEG::File *mpeg=dynamic_cast<TagLib::MPEG::File *>(fileref.file());
|
|
|
|
|
TagLib::ID3v1::Tag *v1=mpeg ? mpeg->ID3v1Tag(false) : 0;
|
|
|
|
|
bool haveV1=v1 && (!v1->title().isEmpty() || !v1->artist().isEmpty() || !v1->album().isEmpty());
|
|
|
|
|
|
|
|
|
|
if (writeTags(fileref, from, to, RgTags(), QByteArray())) {
|
|
|
|
|
if (mpeg && !haveV1) {
|
|
|
|
|
return mpeg->save(TagLib::MPEG::File::ID3v2) ? Update_Modified : Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
return fileref.file()->save() ? Update_Modified : Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
return Update_None;
|
|
|
|
|
return fileref.isNull() ? Update_Failed : update(fileref, from, to, RgTags(), QByteArray());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReplayGain readReplaygain(const QString &fileName)
|
|
|
|
|
@@ -1058,22 +1071,7 @@ Update updateReplaygain(const QString &fileName, const ReplayGain &rg)
|
|
|
|
|
ensureFileTypeResolvers();
|
|
|
|
|
|
|
|
|
|
TagLib::FileRef fileref = getFileRef(fileName);
|
|
|
|
|
|
|
|
|
|
if (fileref.isNull()) {
|
|
|
|
|
return Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TagLib::MPEG::File *mpeg=dynamic_cast<TagLib::MPEG::File *>(fileref.file());
|
|
|
|
|
TagLib::ID3v1::Tag *v1=mpeg ? mpeg->ID3v1Tag(false) : 0;
|
|
|
|
|
bool haveV1=v1 && (!v1->title().isEmpty() || !v1->artist().isEmpty() || !v1->album().isEmpty());
|
|
|
|
|
|
|
|
|
|
if (writeTags(fileref, Song(), Song(), RgTags(rg), QByteArray())) {
|
|
|
|
|
if (mpeg && !haveV1) {
|
|
|
|
|
return mpeg->save(TagLib::MPEG::File::ID3v2) ? Update_Modified : Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
return fileref.file()->save() ? Update_Modified : Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
return Update_None;
|
|
|
|
|
return fileref.isNull() ? Update_Failed : update(fileref, Song(), Song(), RgTags(rg), QByteArray());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Update embedImage(const QString &fileName, const QByteArray &cover)
|
|
|
|
|
@@ -1082,22 +1080,7 @@ Update embedImage(const QString &fileName, const QByteArray &cover)
|
|
|
|
|
ensureFileTypeResolvers();
|
|
|
|
|
|
|
|
|
|
TagLib::FileRef fileref = getFileRef(fileName);
|
|
|
|
|
|
|
|
|
|
if (fileref.isNull()) {
|
|
|
|
|
return Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TagLib::MPEG::File *mpeg=dynamic_cast<TagLib::MPEG::File *>(fileref.file());
|
|
|
|
|
TagLib::ID3v1::Tag *v1=mpeg ? mpeg->ID3v1Tag(false) : 0;
|
|
|
|
|
bool haveV1=v1 && (!v1->title().isEmpty() || !v1->artist().isEmpty() || !v1->album().isEmpty());
|
|
|
|
|
|
|
|
|
|
if (writeTags(fileref, Song(), Song(), RgTags(), cover)) {
|
|
|
|
|
if (mpeg && !haveV1) {
|
|
|
|
|
return mpeg->save(TagLib::MPEG::File::ID3v2) ? Update_Modified : Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
return fileref.file()->save() ? Update_Modified : Update_Failed;
|
|
|
|
|
}
|
|
|
|
|
return Update_None;
|
|
|
|
|
return fileref.isNull() ? Update_Failed : update(fileref, Song(), Song(), RgTags(), cover);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|