From 466d339d9d50b8771a949e156980de3b7d9b568f Mon Sep 17 00:00:00 2001 From: lordmulder Date: Fri, 23 Sep 2011 21:30:55 +0200 Subject: [PATCH] Added support for the non-standard tags "REM DATE" and "REM GENRE" to the CUE Sheet parser. --- src/Config.h | 2 +- src/Global.cpp | 2 +- src/Model_CueSheet.cpp | 111 ++++++++++++++++++++++++++++++++++++- src/Model_CueSheet.h | 6 ++ src/Thread_CueSplitter.cpp | 13 +++++ 5 files changed, 130 insertions(+), 4 deletions(-) diff --git a/src/Config.h b/src/Config.h index 6e10accb..af0d4be2 100644 --- a/src/Config.h +++ b/src/Config.h @@ -30,7 +30,7 @@ #define VER_LAMEXP_MINOR_LO 3 #define VER_LAMEXP_TYPE Beta #define VER_LAMEXP_PATCH 2 -#define VER_LAMEXP_BUILD 692 +#define VER_LAMEXP_BUILD 694 /////////////////////////////////////////////////////////////////////////////// // Tools versions diff --git a/src/Global.cpp b/src/Global.cpp index d7ef932b..aa19d3d1 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -797,7 +797,7 @@ bool lamexp_init_qt(int argc, char* argv[]) lamexp_check_compatibility_mode(NULL, executableName); break; default: - qWarning("Running on an unknown/unsupported OS (%d).\n", static_cast(QSysInfo::windowsVersion() & QSysInfo::WV_NT_based)); + qWarning("Running on an unknown/untested WinNT-based OS.\n"); break; } diff --git a/src/Model_CueSheet.cpp b/src/Model_CueSheet.cpp index 91b8f51c..bdf890bf 100644 --- a/src/Model_CueSheet.cpp +++ b/src/Model_CueSheet.cpp @@ -53,17 +53,22 @@ public: { m_startIndex = std::numeric_limits::quiet_NaN(); m_duration = std::numeric_limits::infinity(); + m_year = 0; } int trackNo(void) { return m_trackNo; } double startIndex(void) { return m_startIndex; } double duration(void) { return m_duration; } QString title(void) { return m_title; } QString performer(void) { return m_performer; } + QString genre(void) { return m_genre; } + unsigned int year(void) { return m_year; } CueSheetFile *parent(void) { return m_parent; } void setStartIndex(double startIndex) { m_startIndex = startIndex; } void setDuration(double duration) { m_duration = duration; } void setTitle(const QString &title, bool update = false) { if(!update || (m_title.isEmpty() && !title.isEmpty())) m_title = title; } void setPerformer(const QString &performer, bool update = false) { if(!update || (m_performer.isEmpty() && !performer.isEmpty())) m_performer = performer; } + void setGenre(const QString &genre, bool update = false) { if(!update || (m_genre.isEmpty() && !m_genre.isEmpty())) m_genre = genre; } + void setYear(const unsigned int year, bool update = false) { if(!update || (year == 0)) m_year = year; } virtual bool isValid(void) { return !(_isnan(m_startIndex) || (m_trackNo < 0)); } virtual const char* type(void) { return "CueSheetTrack"; } private: @@ -72,6 +77,8 @@ private: double m_duration; QString m_title; QString m_performer; + QString m_genre; + unsigned int m_year; CueSheetFile *m_parent; }; @@ -104,6 +111,7 @@ CueSheetModel::CueSheetModel() m_trackIcon(":/icons/control_play_blue.png") { int trackNo = 0; + m_albumYear = 0; for(int i = 0; i < 5; i++) { @@ -455,6 +463,40 @@ QString CueSheetModel::getTrackTitle(int fileIndex, int trackIndex) return QString(); } +QString CueSheetModel::getTrackGenre(int fileIndex, int trackIndex) +{ + QMutexLocker lock(&m_mutex); + + if(fileIndex >= 0 && fileIndex < m_files.count()) + { + CueSheetFile *currentFile = m_files.at(fileIndex); + if(trackIndex >= 0 && trackIndex < currentFile->trackCount()) + { + CueSheetTrack *currentTrack = currentFile->track(trackIndex); + return currentTrack->genre(); + } + } + + return QString(); +} + +unsigned int CueSheetModel::getTrackYear(int fileIndex, int trackIndex) +{ + QMutexLocker lock(&m_mutex); + + if(fileIndex >= 0 && fileIndex < m_files.count()) + { + CueSheetFile *currentFile = m_files.at(fileIndex); + if(trackIndex >= 0 && trackIndex < currentFile->trackCount()) + { + CueSheetTrack *currentTrack = currentFile->track(trackIndex); + return currentTrack->year(); + } + } + + return 0; +} + QString CueSheetModel::getAlbumPerformer(void) { QMutexLocker lock(&m_mutex); @@ -467,6 +509,17 @@ QString CueSheetModel::getAlbumTitle(void) return m_albumTitle; } +QString CueSheetModel::getAlbumGenre(void) +{ + QMutexLocker lock(&m_mutex); + return m_albumGenre; +} + +unsigned int CueSheetModel::getAlbumYear(void) +{ + QMutexLocker lock(&m_mutex); + return m_albumYear; +} //////////////////////////////////////////////////////////// // Cue Sheet Parser //////////////////////////////////////////////////////////// @@ -513,6 +566,8 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic QRegExp rxIndex("^INDEX\\s+(\\d+)\\s+([0-9:]+)$", Qt::CaseInsensitive); QRegExp rxTitle("^TITLE\\s+\"([^\"]+)\"$", Qt::CaseInsensitive); QRegExp rxPerformer("^PERFORMER\\s+\"([^\"]+)\"$", Qt::CaseInsensitive); + QRegExp rxGenre("^REM\\s+GENRE\\s+(\\w+)$", Qt::CaseInsensitive); + QRegExp rxYear("^REM\\s+DATE\\s+(\\d+)$", Qt::CaseInsensitive); bool bPreamble = true; bool bUnsupportedTrack = false; @@ -522,6 +577,8 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic m_albumTitle.clear(); m_albumPerformer.clear(); + m_albumGenre.clear(); + m_albumYear = 0; //Loop over the Cue Sheet until all lines were processed for(int lines = 0; lines < INT_MAX; lines++) @@ -650,7 +707,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic else if(currentFile && currentTrack) { qDebug("%03d Title: <%s>", lines, rxTitle.cap(1).toUtf8().constData()); - currentTrack->setTitle(rxTitle.cap(1)); + currentTrack->setTitle(rxTitle.cap(1).simplified()); } continue; } @@ -665,7 +722,57 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic else if(currentFile && currentTrack) { qDebug("%03d Title: <%s>", lines, rxPerformer.cap(1).toUtf8().constData()); - currentTrack->setPerformer(rxPerformer.cap(1)); + currentTrack->setPerformer(rxPerformer.cap(1).simplified()); + } + continue; + } + + /* --- GENRE --- */ + if(rxGenre.indexIn(line) >= 0) + { + if(bPreamble) + { + QString temp = rxGenre.cap(1).simplified(); + for(int i = 0; g_lamexp_generes[i]; i++) + { + if(temp.compare(g_lamexp_generes[i], Qt::CaseInsensitive) == 0) + { + m_albumGenre = QString(g_lamexp_generes[i]); + break; + } + } + } + else if(currentFile && currentTrack) + { + qDebug("%03d Genre: <%s>", lines, rxGenre.cap(1).toUtf8().constData()); + QString temp = rxGenre.cap(1).simplified(); + for(int i = 0; g_lamexp_generes[i]; i++) + { + if(temp.compare(g_lamexp_generes[i], Qt::CaseInsensitive) == 0) + { + currentTrack->setGenre(QString(g_lamexp_generes[i])); + break; + } + } + } + continue; + } + + /* --- YEAR --- */ + if(rxYear.indexIn(line) >= 0) + { + if(bPreamble) + { + bool ok = false; + unsigned int temp = rxYear.cap(1).toUInt(&ok); + if(ok) m_albumYear = temp; + } + else if(currentFile && currentTrack) + { + qDebug("%03d Year: <%s>", lines, rxPerformer.cap(1).toUtf8().constData()); + bool ok = false; + unsigned int temp = rxYear.cap(1).toUInt(&ok); + if(ok) currentTrack->setYear(temp); } continue; } diff --git a/src/Model_CueSheet.h b/src/Model_CueSheet.h index 43ba8119..8def56cd 100644 --- a/src/Model_CueSheet.h +++ b/src/Model_CueSheet.h @@ -65,8 +65,12 @@ public: void getTrackIndex(int fileIndex, int trackIndex, double *startIndex, double *duration); QString getTrackPerformer(int fileIndex, int trackIndex); QString getTrackTitle(int fileIndex, int trackIndex); + QString getTrackGenre(int fileIndex, int trackIndex); + unsigned int getTrackYear(int fileIndex, int trackIndex); QString getAlbumPerformer(void); QString getAlbumTitle(void); + QString getAlbumGenre(void); + unsigned int getAlbumYear(void); //Cue Sheet functions int loadCueSheet(const QString &cueFile, QCoreApplication *application = NULL); @@ -81,6 +85,8 @@ private: QList m_files; QString m_albumTitle; QString m_albumPerformer; + QString m_albumGenre; + unsigned int m_albumYear; const QIcon m_fileIcon; const QIcon m_trackIcon; diff --git a/src/Thread_CueSplitter.cpp b/src/Thread_CueSplitter.cpp index 6b27841e..656ec4df 100644 --- a/src/Thread_CueSplitter.cpp +++ b/src/Thread_CueSplitter.cpp @@ -148,6 +148,8 @@ void CueSplitter::run() int nFiles = m_model->getFileCount(); QString albumPerformer = m_model->getAlbumPerformer(); QString albumTitle = m_model->getAlbumTitle(); + QString albumGenre = m_model->getAlbumGenre(); + unsigned int albumYear = m_model->getAlbumYear(); //Now split all files for(int i = 0; i < nFiles; i++) @@ -174,8 +176,11 @@ void CueSplitter::run() AudioFileModel trackMetaInfo(QString().sprintf("cue://File%02d/Track%02d", i, j)); trackMetaInfo.setFileName(m_model->getTrackTitle(i, j)); trackMetaInfo.setFileArtist(m_model->getTrackPerformer(i, j)); + trackMetaInfo.setFileGenre(m_model->getTrackGenre(i, j)); + trackMetaInfo.setFileYear(m_model->getTrackYear(i, j)); trackMetaInfo.setFilePosition(trackNo); + //Apply album meta data on files if(!albumTitle.isEmpty()) { trackMetaInfo.setFileAlbum(albumTitle); @@ -184,6 +189,14 @@ void CueSplitter::run() { trackMetaInfo.setFileArtist(albumPerformer); } + if(!albumGenre.isEmpty() && trackMetaInfo.fileGenre().isEmpty()) + { + trackMetaInfo.setFileGenre(albumGenre); + } + if((albumYear > 0) && (trackMetaInfo.fileYear() == 0)) + { + trackMetaInfo.setFileYear(albumYear); + } if(_finite(trackLength)) { trackMetaInfo.setFileDuration(static_cast(abs(trackLength)));