Added support for the non-standard tags "REM DATE" and "REM GENRE" to the CUE Sheet parser.

This commit is contained in:
LoRd_MuldeR 2011-09-23 21:30:55 +02:00
parent 4e79fc2fc5
commit 466d339d9d
5 changed files with 130 additions and 4 deletions

View File

@ -30,7 +30,7 @@
#define VER_LAMEXP_MINOR_LO 3 #define VER_LAMEXP_MINOR_LO 3
#define VER_LAMEXP_TYPE Beta #define VER_LAMEXP_TYPE Beta
#define VER_LAMEXP_PATCH 2 #define VER_LAMEXP_PATCH 2
#define VER_LAMEXP_BUILD 692 #define VER_LAMEXP_BUILD 694
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Tools versions // Tools versions

View File

@ -797,7 +797,7 @@ bool lamexp_init_qt(int argc, char* argv[])
lamexp_check_compatibility_mode(NULL, executableName); lamexp_check_compatibility_mode(NULL, executableName);
break; break;
default: default:
qWarning("Running on an unknown/unsupported OS (%d).\n", static_cast<int>(QSysInfo::windowsVersion() & QSysInfo::WV_NT_based)); qWarning("Running on an unknown/untested WinNT-based OS.\n");
break; break;
} }

View File

@ -53,17 +53,22 @@ public:
{ {
m_startIndex = std::numeric_limits<double>::quiet_NaN(); m_startIndex = std::numeric_limits<double>::quiet_NaN();
m_duration = std::numeric_limits<double>::infinity(); m_duration = std::numeric_limits<double>::infinity();
m_year = 0;
} }
int trackNo(void) { return m_trackNo; } int trackNo(void) { return m_trackNo; }
double startIndex(void) { return m_startIndex; } double startIndex(void) { return m_startIndex; }
double duration(void) { return m_duration; } double duration(void) { return m_duration; }
QString title(void) { return m_title; } QString title(void) { return m_title; }
QString performer(void) { return m_performer; } 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; } CueSheetFile *parent(void) { return m_parent; }
void setStartIndex(double startIndex) { m_startIndex = startIndex; } void setStartIndex(double startIndex) { m_startIndex = startIndex; }
void setDuration(double duration) { m_duration = duration; } 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 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 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 bool isValid(void) { return !(_isnan(m_startIndex) || (m_trackNo < 0)); }
virtual const char* type(void) { return "CueSheetTrack"; } virtual const char* type(void) { return "CueSheetTrack"; }
private: private:
@ -72,6 +77,8 @@ private:
double m_duration; double m_duration;
QString m_title; QString m_title;
QString m_performer; QString m_performer;
QString m_genre;
unsigned int m_year;
CueSheetFile *m_parent; CueSheetFile *m_parent;
}; };
@ -104,6 +111,7 @@ CueSheetModel::CueSheetModel()
m_trackIcon(":/icons/control_play_blue.png") m_trackIcon(":/icons/control_play_blue.png")
{ {
int trackNo = 0; int trackNo = 0;
m_albumYear = 0;
for(int i = 0; i < 5; i++) for(int i = 0; i < 5; i++)
{ {
@ -455,6 +463,40 @@ QString CueSheetModel::getTrackTitle(int fileIndex, int trackIndex)
return QString(); 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) QString CueSheetModel::getAlbumPerformer(void)
{ {
QMutexLocker lock(&m_mutex); QMutexLocker lock(&m_mutex);
@ -467,6 +509,17 @@ QString CueSheetModel::getAlbumTitle(void)
return m_albumTitle; 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 // 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 rxIndex("^INDEX\\s+(\\d+)\\s+([0-9:]+)$", Qt::CaseInsensitive);
QRegExp rxTitle("^TITLE\\s+\"([^\"]+)\"$", Qt::CaseInsensitive); QRegExp rxTitle("^TITLE\\s+\"([^\"]+)\"$", Qt::CaseInsensitive);
QRegExp rxPerformer("^PERFORMER\\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 bPreamble = true;
bool bUnsupportedTrack = false; bool bUnsupportedTrack = false;
@ -522,6 +577,8 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic
m_albumTitle.clear(); m_albumTitle.clear();
m_albumPerformer.clear(); m_albumPerformer.clear();
m_albumGenre.clear();
m_albumYear = 0;
//Loop over the Cue Sheet until all lines were processed //Loop over the Cue Sheet until all lines were processed
for(int lines = 0; lines < INT_MAX; lines++) 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) else if(currentFile && currentTrack)
{ {
qDebug("%03d Title: <%s>", lines, rxTitle.cap(1).toUtf8().constData()); qDebug("%03d Title: <%s>", lines, rxTitle.cap(1).toUtf8().constData());
currentTrack->setTitle(rxTitle.cap(1)); currentTrack->setTitle(rxTitle.cap(1).simplified());
} }
continue; continue;
} }
@ -665,7 +722,57 @@ int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplic
else if(currentFile && currentTrack) else if(currentFile && currentTrack)
{ {
qDebug("%03d Title: <%s>", lines, rxPerformer.cap(1).toUtf8().constData()); 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; continue;
} }

View File

@ -65,8 +65,12 @@ public:
void getTrackIndex(int fileIndex, int trackIndex, double *startIndex, double *duration); void getTrackIndex(int fileIndex, int trackIndex, double *startIndex, double *duration);
QString getTrackPerformer(int fileIndex, int trackIndex); QString getTrackPerformer(int fileIndex, int trackIndex);
QString getTrackTitle(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 getAlbumPerformer(void);
QString getAlbumTitle(void); QString getAlbumTitle(void);
QString getAlbumGenre(void);
unsigned int getAlbumYear(void);
//Cue Sheet functions //Cue Sheet functions
int loadCueSheet(const QString &cueFile, QCoreApplication *application = NULL); int loadCueSheet(const QString &cueFile, QCoreApplication *application = NULL);
@ -81,6 +85,8 @@ private:
QList<CueSheetFile*> m_files; QList<CueSheetFile*> m_files;
QString m_albumTitle; QString m_albumTitle;
QString m_albumPerformer; QString m_albumPerformer;
QString m_albumGenre;
unsigned int m_albumYear;
const QIcon m_fileIcon; const QIcon m_fileIcon;
const QIcon m_trackIcon; const QIcon m_trackIcon;

View File

@ -148,6 +148,8 @@ void CueSplitter::run()
int nFiles = m_model->getFileCount(); int nFiles = m_model->getFileCount();
QString albumPerformer = m_model->getAlbumPerformer(); QString albumPerformer = m_model->getAlbumPerformer();
QString albumTitle = m_model->getAlbumTitle(); QString albumTitle = m_model->getAlbumTitle();
QString albumGenre = m_model->getAlbumGenre();
unsigned int albumYear = m_model->getAlbumYear();
//Now split all files //Now split all files
for(int i = 0; i < nFiles; i++) 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)); AudioFileModel trackMetaInfo(QString().sprintf("cue://File%02d/Track%02d", i, j));
trackMetaInfo.setFileName(m_model->getTrackTitle(i, j)); trackMetaInfo.setFileName(m_model->getTrackTitle(i, j));
trackMetaInfo.setFileArtist(m_model->getTrackPerformer(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); trackMetaInfo.setFilePosition(trackNo);
//Apply album meta data on files
if(!albumTitle.isEmpty()) if(!albumTitle.isEmpty())
{ {
trackMetaInfo.setFileAlbum(albumTitle); trackMetaInfo.setFileAlbum(albumTitle);
@ -184,6 +189,14 @@ void CueSplitter::run()
{ {
trackMetaInfo.setFileArtist(albumPerformer); trackMetaInfo.setFileArtist(albumPerformer);
} }
if(!albumGenre.isEmpty() && trackMetaInfo.fileGenre().isEmpty())
{
trackMetaInfo.setFileGenre(albumGenre);
}
if((albumYear > 0) && (trackMetaInfo.fileYear() == 0))
{
trackMetaInfo.setFileYear(albumYear);
}
if(_finite(trackLength)) if(_finite(trackLength))
{ {
trackMetaInfo.setFileDuration(static_cast<unsigned int>(abs(trackLength))); trackMetaInfo.setFileDuration(static_cast<unsigned int>(abs(trackLength)));