aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/Input/cue/cueparser.cpp80
-rw-r--r--src/plugins/Input/cue/cueparser.h14
-rw-r--r--src/plugins/Input/cue/decoder_cue.cpp11
-rw-r--r--src/plugins/Input/flac/cueparser.cpp119
-rw-r--r--src/plugins/Input/flac/cueparser.h21
-rw-r--r--src/plugins/Input/flac/decoder_flac.cpp2
-rw-r--r--src/plugins/Input/wavpack/cueparser.cpp118
-rw-r--r--src/plugins/Input/wavpack/cueparser.h20
-rw-r--r--src/plugins/Input/wavpack/decoder_wavpack.cpp2
9 files changed, 287 insertions, 100 deletions
diff --git a/src/plugins/Input/cue/cueparser.cpp b/src/plugins/Input/cue/cueparser.cpp
index a5e1398d1..3ad5e9372 100644
--- a/src/plugins/Input/cue/cueparser.cpp
+++ b/src/plugins/Input/cue/cueparser.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2008-2010 by Ilya Kotov *
+ * Copyright (C) 2008-2011 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -81,6 +81,7 @@ CUEParser::CUEParser(const QString &url)
textStream.setCodec(codec);
QString album, genre, date, comment, artist, file_path;
bool new_file = false;
+ double album_gain = 0.0, album_peak = 0.0;
while (!textStream.atEnd())
{
@@ -91,14 +92,14 @@ CUEParser::CUEParser(const QString &url)
if (words[0] == "FILE")
{
- if(!m_infoList.isEmpty())
+ if(!m_tracks.isEmpty())
{
QList <FileInfo *> f_list = MetaDataManager::instance()->createPlayList(file_path, false);
qint64 l = f_list.isEmpty() ? 0 : f_list.at(0)->length() * 1000;
- if (l > m_offsets.last())
- m_infoList.last().setLength(l - m_offsets.last());
+ if (l > m_tracks.last()->offset)
+ m_tracks.last()->info.setLength(l - m_tracks.last()->offset);
else
- m_infoList.last().setLength(0);
+ m_tracks.last()->info.setLength(0);
}
file_path = getDirtyPath(fileName, QFileInfo(fileName).dir().filePath(words[1]));
new_file = true;
@@ -106,17 +107,17 @@ CUEParser::CUEParser(const QString &url)
else if (words[0] == "PERFORMER")
{
- if(m_infoList.isEmpty())
+ if(m_tracks.isEmpty())
artist = words[1];
else
- m_infoList.last().setMetaData(Qmmp::ARTIST, words[1]);
+ m_tracks.last()->info.setMetaData(Qmmp::ARTIST, words[1]);
}
else if (words[0] == "TITLE")
{
- if(m_infoList.isEmpty())
+ if(m_tracks.isEmpty())
album = words[1];
else
- m_infoList.last().setMetaData(Qmmp::TITLE, words[1]);
+ m_tracks.last()->info.setMetaData(Qmmp::TITLE, words[1]);
}
else if (words[0] == "TRACK")
{
@@ -132,18 +133,22 @@ CUEParser::CUEParser(const QString &url)
info.setMetaData(Qmmp::YEAR, date);
info.setMetaData(Qmmp::COMMENT, comment);
info.setMetaData(Qmmp::ARTIST, artist);
- m_infoList << info;
- m_offsets << 0;
- m_files << file_path;
+
+ m_tracks << new CUETrack;
+ m_tracks.last()->info = info;
+ m_tracks.last()->offset = 0;
+ m_tracks.last()->file = file_path;
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_ALBUM_GAIN, album_gain);
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_ALBUM_PEAK, album_peak);
}
else if (words[0] == "INDEX" && words[1] == "01")
{
- if (m_infoList.isEmpty())
+ if (m_tracks.isEmpty())
continue;
- m_offsets.last() = getLength(words[2]);
- int c = m_infoList.count();
+ m_tracks.last()->offset = getLength(words[2]);
+ int c = m_tracks.count();
if(c > 1 && !new_file)
- m_infoList[c - 2].setLength(m_offsets[c - 1] - m_offsets[c - 2]);
+ m_tracks[c - 2]->info.setLength(m_tracks[c - 1]->offset - m_tracks[c - 2]->offset);
new_file = false;
}
else if (words[0] == "REM")
@@ -156,6 +161,14 @@ CUEParser::CUEParser(const QString &url)
date = words[2];
else if (words[1] == "COMMENT")
comment = words[2];
+ else if (words[1] == "REPLAYGAIN_ALBUM_GAIN")
+ album_gain = words[2].toDouble();
+ else if (words[1] == "REPLAYGAIN_ALBUM_PEAK")
+ album_peak = words[2].toDouble();
+ else if (words[1] == "REPLAYGAIN_TRACK_GAIN" && !m_tracks.isEmpty())
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_TRACK_GAIN, words[2].toDouble());
+ else if (words[1] == "REPLAYGAIN_TRACK_PEAK" && !m_tracks.isEmpty())
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_TRACK_PEAK, words[2].toDouble());
}
}
file.close();
@@ -163,7 +176,7 @@ CUEParser::CUEParser(const QString &url)
if(analyser)
enca_analyser_free(analyser);
#endif
- if(m_infoList.isEmpty())
+ if(m_tracks.isEmpty())
{
qWarning("CUEParser: invalid cue file");
return;
@@ -171,55 +184,62 @@ CUEParser::CUEParser(const QString &url)
//calculate last item length
QList <FileInfo *> f_list = MetaDataManager::instance()->createPlayList(file_path, false);
qint64 l = f_list.isEmpty() ? 0 : f_list.at(0)->length() * 1000;
- if (l > m_offsets.last())
- m_infoList.last().setLength(l - m_offsets.last());
+ if (l > m_tracks.last()->offset)
+ m_tracks.last()->info.setLength(l - m_tracks.last()->offset);
else
- m_infoList.last().setLength(0);
+ m_tracks.last()->info.setLength(0);
}
CUEParser::~CUEParser()
{
+ qDeleteAll(m_tracks);
+ m_tracks.clear();
}
QList<FileInfo*> CUEParser::createPlayList()
{
QList<FileInfo*> list;
- foreach(FileInfo info, m_infoList)
+ foreach(CUETrack *track, m_tracks)
{
- list << new FileInfo(info);
- list.last()->setLength(list.last()->length()/1000);
+ list << new FileInfo(track->info);
+ list.last()->setLength(track->info.length()/1000);
}
return list;
}
const QString CUEParser::filePath(int track) const
{
- return (track <= m_files.size()) ? m_files[track - 1] : QString();
+ return (track <= m_tracks.count()) ? m_tracks[track - 1]->file : QString();
}
qint64 CUEParser::offset(int track) const
{
- return m_offsets.at(track - 1);
+ return m_tracks.at(track - 1)->offset;
}
qint64 CUEParser::length(int track) const
{
- return m_infoList.at(track - 1).length();
+ return m_tracks.at(track - 1)->info.length();
}
int CUEParser::count() const
{
- return m_infoList.count();
+ return m_tracks.count();
}
FileInfo *CUEParser::info(int track)
{
- return &m_infoList[track - 1];
+ return &m_tracks.at(track - 1)->info;
+}
+
+const QString CUEParser::trackURL(int track) const
+{
+ return m_tracks.at(track - 1)->info.path();
}
-const QString CUEParser::trackURL(int track)
+const QMap<Qmmp::ReplayGainKey, double> CUEParser::replayGain(int track) const
{
- return m_infoList[track - 1].path();
+ return m_tracks.at(track - 1)->replayGain;
}
QStringList CUEParser::splitLine(const QString &line)
diff --git a/src/plugins/Input/cue/cueparser.h b/src/plugins/Input/cue/cueparser.h
index 5c41a7811..124b5fa39 100644
--- a/src/plugins/Input/cue/cueparser.h
+++ b/src/plugins/Input/cue/cueparser.h
@@ -45,12 +45,18 @@ public:
qint64 length(int track) const;
int count() const;
FileInfo *info(int track);
- const QString trackURL(int track);
+ const QString trackURL(int track) const;
+ const QMap<Qmmp::ReplayGainKey, double> replayGain(int track) const;
private:
- QList <FileInfo> m_infoList;
- QList <qint64> m_offsets;
- QStringList m_files;
+ struct CUETrack
+ {
+ FileInfo info;
+ qint64 offset;
+ QString file;
+ QMap<Qmmp::ReplayGainKey, double> replayGain;
+ };
+ QList <CUETrack * > m_tracks;
bool m_dirty;
QStringList splitLine(const QString &line);
qint64 getLength(const QString &str);
diff --git a/src/plugins/Input/cue/decoder_cue.cpp b/src/plugins/Input/cue/decoder_cue.cpp
index dd6c90a5f..2551dfbf5 100644
--- a/src/plugins/Input/cue/decoder_cue.cpp
+++ b/src/plugins/Input/cue/decoder_cue.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2008-2009 by Ilya Kotov *
+ * Copyright (C) 2008-2011 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -18,16 +18,14 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#include <QObject>
+#include <QFile>
#include <qmmp/buffer.h>
#include <qmmp/output.h>
#include <qmmp/recycler.h>
#include <qmmp/fileinfo.h>
#include <qmmp/decoderfactory.h>
#include <qmmp/soundcore.h>
-
-#include <QObject>
-#include <QFile>
-
#include "cueparser.h"
#include "decoder_cue.h"
@@ -102,7 +100,7 @@ bool DecoderCUE::initialize()
configure(m_decoder->audioParameters().sampleRate(),
m_decoder->audioParameters().channels(),
m_decoder->audioParameters().format());
- setReplayGainInfo(m_decoder->replayGainInfo());
+ setReplayGainInfo(m_parser->replayGain(m_track));
length_in_bytes = audioParameters().sampleRate() *
audioParameters().channels() *
audioParameters().sampleSize() * m_length/1000;
@@ -195,6 +193,7 @@ void DecoderCUE::next()
audioParameters().channels() *
audioParameters().sampleSize() * m_length/1000;
addMetaData(m_parser->info(m_track)->metaData());
+ setReplayGainInfo(m_parser->replayGain(m_track));
m_totalBytes = 0;
}
}
diff --git a/src/plugins/Input/flac/cueparser.cpp b/src/plugins/Input/flac/cueparser.cpp
index 89c39c889..afe277919 100644
--- a/src/plugins/Input/flac/cueparser.cpp
+++ b/src/plugins/Input/flac/cueparser.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2008-2010 by Ilya Kotov *
+ * Copyright (C) 2008-2011 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -18,8 +18,13 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#include <QFile>
+#include <QDir>
+#include <QDirIterator>
+#include <QSettings>
#include <QTextStream>
#include <QTextCodec>
+#include <qmmp/decoder.h>
#include <qmmp/metadatamanager.h>
#include "cueparser.h"
@@ -30,6 +35,7 @@ CUEParser::CUEParser(const QByteArray &array, const QString &fileName)
textStream.setCodec("UTF-8");
m_filePath = fileName;
QString artist;
+ double album_peak = 0.0, album_gain = 0.0;
while (!textStream.atEnd())
{
QString line = textStream.readLine().trimmed();
@@ -39,17 +45,17 @@ CUEParser::CUEParser(const QByteArray &array, const QString &fileName)
if (words[0] == "PERFORMER")
{
- if(m_infoList.isEmpty())
+ if(m_tracks.isEmpty())
artist = words[1];
else
- m_infoList.last().setMetaData(Qmmp::ARTIST, words[1]);
+ m_tracks.last()->info.setMetaData(Qmmp::ARTIST, words[1]);
}
else if (words[0] == "TITLE")
{
- if(m_infoList.isEmpty())
+ if(m_tracks.isEmpty())
album = words[1];
else
- m_infoList.last().setMetaData(Qmmp::TITLE, words[1]);
+ m_tracks.last()->info.setMetaData(Qmmp::TITLE, words[1]);
}
else if (words[0] == "TRACK")
{
@@ -65,17 +71,21 @@ CUEParser::CUEParser(const QByteArray &array, const QString &fileName)
info.setMetaData(Qmmp::YEAR, date);
info.setMetaData(Qmmp::COMMENT, comment);
info.setMetaData(Qmmp::ARTIST, artist);
- m_infoList << info;
- m_offsets << 0;
+
+ m_tracks << new CUETrack;
+ m_tracks.last()->info = info;
+ m_tracks.last()->offset = 0;
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_ALBUM_GAIN, album_gain);
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_ALBUM_PEAK, album_peak);
}
else if (words[0] == "INDEX" && words[1] == "01")
{
- if (m_infoList.isEmpty())
+ if (m_tracks.isEmpty())
continue;
- m_offsets.last() = getLength(words[2]);
- int c = m_infoList.count();
+ m_tracks.last()->offset = getLength(words[2]);
+ int c = m_tracks.count();
if(c > 1)
- m_infoList[c - 2].setLength(m_offsets[c - 1] - m_offsets[c - 2]);
+ m_tracks[c - 2]->info.setLength(m_tracks[c - 1]->offset - m_tracks[c - 2]->offset);
}
else if (words[0] == "REM")
{
@@ -87,9 +97,17 @@ CUEParser::CUEParser(const QByteArray &array, const QString &fileName)
date = words[2];
else if (words[1] == "COMMENT")
comment = words[2];
+ else if (words[1] == "REPLAYGAIN_ALBUM_GAIN")
+ album_gain = words[2].toDouble();
+ else if (words[1] == "REPLAYGAIN_ALBUM_PEAK")
+ album_peak = words[2].toDouble();
+ else if (words[1] == "REPLAYGAIN_TRACK_GAIN" && !m_tracks.isEmpty())
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_TRACK_GAIN, words[2].toDouble());
+ else if (words[1] == "REPLAYGAIN_TRACK_PEAK" && !m_tracks.isEmpty())
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_TRACK_PEAK, words[2].toDouble());
}
}
- if(m_infoList.isEmpty())
+ if(m_tracks.isEmpty())
{
qWarning("CUEParser: invalid cue file");
return;
@@ -97,24 +115,25 @@ CUEParser::CUEParser(const QByteArray &array, const QString &fileName)
//calculate last item length
QList <FileInfo *> f_list = MetaDataManager::instance()->createPlayList(m_filePath, false);
qint64 l = f_list.isEmpty() ? 0 : f_list.at(0)->length() * 1000;
- if (l > m_offsets.last())
- m_infoList.last().setLength(l - m_offsets.last());
+ if (l > m_tracks.last()->offset)
+ m_tracks.last()->info.setLength(l - m_tracks.last()->offset);
else
- m_infoList.last().setLength(0);
+ m_tracks.last()->info.setLength(0);
}
-
CUEParser::~CUEParser()
{
+ qDeleteAll(m_tracks);
+ m_tracks.clear();
}
QList<FileInfo*> CUEParser::createPlayList()
{
QList<FileInfo*> list;
- foreach(FileInfo info, m_infoList)
+ foreach(CUETrack *track, m_tracks)
{
- list << new FileInfo(info);
- list.last()->setLength(list.last()->length()/1000);
+ list << new FileInfo(track->info);
+ list.last()->setLength(track->info.length()/1000);
}
return list;
}
@@ -126,27 +145,32 @@ const QString CUEParser::filePath() const
qint64 CUEParser::offset(int track) const
{
- return m_offsets.at(track - 1);
+ return m_tracks.at(track - 1)->offset;
}
qint64 CUEParser::length(int track) const
{
- return m_infoList.at(track - 1).length();
+ return m_tracks.at(track - 1)->info.length();
}
int CUEParser::count() const
{
- return m_infoList.count();
+ return m_tracks.count();
}
FileInfo *CUEParser::info(int track)
{
- return &m_infoList[track - 1];
+ return &m_tracks.at(track - 1)->info;
}
const QString CUEParser::trackURL(int track) const
{
- return m_infoList[track - 1].path();
+ return m_tracks.at(track - 1)->info.path();
+}
+
+const QMap<Qmmp::ReplayGainKey, double> CUEParser::replayGain(int track) const
+{
+ return m_tracks.at(track - 1)->replayGain;
}
QStringList CUEParser::splitLine(const QString &line)
@@ -187,3 +211,50 @@ qint64 CUEParser::getLength(const QString &str)
return (qint64)list.at(0).toInt()*60000 + list.at(1).toInt()*1000 + list.at(2).toInt()*1000/75;
return 0;
}
+
+QString CUEParser::getDirtyPath(const QString &cue, const QString &path)
+{
+
+ if (Decoder::findByPath(path) || ! m_dirty)
+ return path;
+
+ QStringList candidates;
+ QDirIterator it(QFileInfo(path).dir().path(), QDir::Files);
+ while (it.hasNext())
+ {
+ it.next();
+ QString f = it.filePath();
+ if ((f != cue) && Decoder::findByPath(f))
+ candidates.push_back(f);
+ }
+
+ if (candidates.empty())
+ return path;
+ else if (candidates.count() == 1)
+ return candidates.first();
+
+ int dot = cue.lastIndexOf('.');
+ if (dot != -1)
+ {
+ QRegExp r(QRegExp::escape(cue.left(dot)) + "\\.[^\\.]+$");
+
+ int index = candidates.indexOf(r);
+ int rindex = candidates.lastIndexOf(r);
+
+ if ((index != -1) && (index == rindex))
+ return candidates[index];
+ }
+ dot = path.lastIndexOf('.');
+ if (dot != -1)
+ {
+ QRegExp r(QRegExp::escape(path.left(dot)) + "\\.[^\\.]+$");
+
+ int index = candidates.indexOf(r);
+ int rindex = candidates.lastIndexOf(r);
+
+ if ((index != -1) && (index == rindex))
+ return candidates[index];
+ }
+
+ return path;
+}
diff --git a/src/plugins/Input/flac/cueparser.h b/src/plugins/Input/flac/cueparser.h
index 5e4e0ea2d..2437065cf 100644
--- a/src/plugins/Input/flac/cueparser.h
+++ b/src/plugins/Input/flac/cueparser.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2008-2009 by Ilya Kotov *
+ * Copyright (C) 2008-2011 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -22,10 +22,10 @@
#include <QList>
#include <QMap>
-#include <QByteArray>
#include <QString>
#include <QStringList>
-
+#include <QUrl>
+#include <qmmp/qmmp.h>
#include <qmmp/fileinfo.h>
@@ -46,14 +46,21 @@ public:
int count() const;
FileInfo *info(int track);
const QString trackURL(int track) const;
+ const QMap<Qmmp::ReplayGainKey, double> replayGain(int track) const;
private:
- QString m_filePath;
- QList <FileInfo> m_infoList;
- QList <qint64> m_offsets;
+ struct CUETrack
+ {
+ FileInfo info;
+ qint64 offset;
+ QMap<Qmmp::ReplayGainKey, double> replayGain;
+ };
+ QList <CUETrack * > m_tracks;
+ bool m_dirty;
QStringList splitLine(const QString &line);
qint64 getLength(const QString &str);
-
+ QString getDirtyPath(const QString &cue, const QString &path);
+ QString m_filePath;
};
#endif
diff --git a/src/plugins/Input/flac/decoder_flac.cpp b/src/plugins/Input/flac/decoder_flac.cpp
index 00b0636aa..f6aee476e 100644
--- a/src/plugins/Input/flac/decoder_flac.cpp
+++ b/src/plugins/Input/flac/decoder_flac.cpp
@@ -426,6 +426,7 @@ bool DecoderFLAC::initialize()
length_in_bytes = audioParameters().sampleRate() *
audioParameters().channels() *
audioParameters().sampleSize() * m_length/1000;
+ setReplayGainInfo(m_parser->replayGain(m_track));
seek(0);
}
m_totalBytes = 0;
@@ -542,6 +543,7 @@ void DecoderFLAC::next()
audioParameters().channels() *
audioParameters().sampleSize() * m_length/1000;
addMetaData(m_parser->info(m_track)->metaData());
+ setReplayGainInfo(m_parser->replayGain(m_track));
m_totalBytes = 0;
}
}
diff --git a/src/plugins/Input/wavpack/cueparser.cpp b/src/plugins/Input/wavpack/cueparser.cpp
index cc55c81a7..537a7c35d 100644
--- a/src/plugins/Input/wavpack/cueparser.cpp
+++ b/src/plugins/Input/wavpack/cueparser.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2008-2010 by Ilya Kotov *
+ * Copyright (C) 2008-2011 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -18,8 +18,13 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#include <QFile>
+#include <QDir>
+#include <QDirIterator>
+#include <QSettings>
#include <QTextStream>
#include <QTextCodec>
+#include <qmmp/decoder.h>
#include <qmmp/metadatamanager.h>
#include "cueparser.h"
@@ -30,6 +35,7 @@ CUEParser::CUEParser(const QByteArray &array, const QString &fileName)
textStream.setCodec("UTF-8");
m_filePath = fileName;
QString artist;
+ double album_peak = 0.0, album_gain = 0.0;
while (!textStream.atEnd())
{
QString line = textStream.readLine().trimmed();
@@ -39,17 +45,17 @@ CUEParser::CUEParser(const QByteArray &array, const QString &fileName)
if (words[0] == "PERFORMER")
{
- if(m_infoList.isEmpty())
+ if(m_tracks.isEmpty())
artist = words[1];
else
- m_infoList.last().setMetaData(Qmmp::ARTIST, words[1]);
+ m_tracks.last()->info.setMetaData(Qmmp::ARTIST, words[1]);
}
else if (words[0] == "TITLE")
{
- if(m_infoList.isEmpty())
+ if(m_tracks.isEmpty())
album = words[1];
else
- m_infoList.last().setMetaData(Qmmp::TITLE, words[1]);
+ m_tracks.last()->info.setMetaData(Qmmp::TITLE, words[1]);
}
else if (words[0] == "TRACK")
{
@@ -65,17 +71,21 @@ CUEParser::CUEParser(const QByteArray &array, const QString &fileName)
info.setMetaData(Qmmp::YEAR, date);
info.setMetaData(Qmmp::COMMENT, comment);
info.setMetaData(Qmmp::ARTIST, artist);
- m_infoList << info;
- m_offsets << 0;
+
+ m_tracks << new CUETrack;
+ m_tracks.last()->info = info;
+ m_tracks.last()->offset = 0;
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_ALBUM_GAIN, album_gain);
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_ALBUM_PEAK, album_peak);
}
else if (words[0] == "INDEX" && words[1] == "01")
{
- if (m_infoList.isEmpty())
+ if (m_tracks.isEmpty())
continue;
- m_offsets.last() = getLength(words[2]);
- int c = m_infoList.count();
+ m_tracks.last()->offset = getLength(words[2]);
+ int c = m_tracks.count();
if(c > 1)
- m_infoList[c - 2].setLength(m_offsets[c - 1] - m_offsets[c - 2]);
+ m_tracks[c - 2]->info.setLength(m_tracks[c - 1]->offset - m_tracks[c - 2]->offset);
}
else if (words[0] == "REM")
{
@@ -87,9 +97,17 @@ CUEParser::CUEParser(const QByteArray &array, const QString &fileName)
date = words[2];
else if (words[1] == "COMMENT")
comment = words[2];
+ else if (words[1] == "REPLAYGAIN_ALBUM_GAIN")
+ album_gain = words[2].toDouble();
+ else if (words[1] == "REPLAYGAIN_ALBUM_PEAK")
+ album_peak = words[2].toDouble();
+ else if (words[1] == "REPLAYGAIN_TRACK_GAIN" && !m_tracks.isEmpty())
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_TRACK_GAIN, words[2].toDouble());
+ else if (words[1] == "REPLAYGAIN_TRACK_PEAK" && !m_tracks.isEmpty())
+ m_tracks.last()->replayGain.insert(Qmmp::REPLAYGAIN_TRACK_PEAK, words[2].toDouble());
}
}
- if(m_infoList.isEmpty())
+ if(m_tracks.isEmpty())
{
qWarning("CUEParser: invalid cue file");
return;
@@ -97,23 +115,25 @@ CUEParser::CUEParser(const QByteArray &array, const QString &fileName)
//calculate last item length
QList <FileInfo *> f_list = MetaDataManager::instance()->createPlayList(m_filePath, false);
qint64 l = f_list.isEmpty() ? 0 : f_list.at(0)->length() * 1000;
- if (l > m_offsets.last())
- m_infoList.last().setLength(l - m_offsets.last());
+ if (l > m_tracks.last()->offset)
+ m_tracks.last()->info.setLength(l - m_tracks.last()->offset);
else
- m_infoList.last().setLength(0);
+ m_tracks.last()->info.setLength(0);
}
CUEParser::~CUEParser()
{
+ qDeleteAll(m_tracks);
+ m_tracks.clear();
}
QList<FileInfo*> CUEParser::createPlayList()
{
QList<FileInfo*> list;
- foreach(FileInfo info, m_infoList)
+ foreach(CUETrack *track, m_tracks)
{
- list << new FileInfo(info);
- list.last()->setLength(list.last()->length()/1000);
+ list << new FileInfo(track->info);
+ list.last()->setLength(track->info.length()/1000);
}
return list;
}
@@ -125,27 +145,32 @@ const QString CUEParser::filePath() const
qint64 CUEParser::offset(int track) const
{
- return m_offsets.at(track - 1);
+ return m_tracks.at(track - 1)->offset;
}
qint64 CUEParser::length(int track) const
{
- return m_infoList.at(track - 1).length();
+ return m_tracks.at(track - 1)->info.length();
}
int CUEParser::count() const
{
- return m_infoList.count();
+ return m_tracks.count();
}
FileInfo *CUEParser::info(int track)
{
- return &m_infoList[track - 1];
+ return &m_tracks.at(track - 1)->info;
}
const QString CUEParser::trackURL(int track) const
{
- return m_infoList[track - 1].path();
+ return m_tracks.at(track - 1)->info.path();
+}
+
+const QMap<Qmmp::ReplayGainKey, double> CUEParser::replayGain(int track) const
+{
+ return m_tracks.at(track - 1)->replayGain;
}
QStringList CUEParser::splitLine(const QString &line)
@@ -186,3 +211,50 @@ qint64 CUEParser::getLength(const QString &str)
return (qint64)list.at(0).toInt()*60000 + list.at(1).toInt()*1000 + list.at(2).toInt()*1000/75;
return 0;
}
+
+QString CUEParser::getDirtyPath(const QString &cue, const QString &path)
+{
+
+ if (Decoder::findByPath(path) || ! m_dirty)
+ return path;
+
+ QStringList candidates;
+ QDirIterator it(QFileInfo(path).dir().path(), QDir::Files);
+ while (it.hasNext())
+ {
+ it.next();
+ QString f = it.filePath();
+ if ((f != cue) && Decoder::findByPath(f))
+ candidates.push_back(f);
+ }
+
+ if (candidates.empty())
+ return path;
+ else if (candidates.count() == 1)
+ return candidates.first();
+
+ int dot = cue.lastIndexOf('.');
+ if (dot != -1)
+ {
+ QRegExp r(QRegExp::escape(cue.left(dot)) + "\\.[^\\.]+$");
+
+ int index = candidates.indexOf(r);
+ int rindex = candidates.lastIndexOf(r);
+
+ if ((index != -1) && (index == rindex))
+ return candidates[index];
+ }
+ dot = path.lastIndexOf('.');
+ if (dot != -1)
+ {
+ QRegExp r(QRegExp::escape(path.left(dot)) + "\\.[^\\.]+$");
+
+ int index = candidates.indexOf(r);
+ int rindex = candidates.lastIndexOf(r);
+
+ if ((index != -1) && (index == rindex))
+ return candidates[index];
+ }
+
+ return path;
+}
diff --git a/src/plugins/Input/wavpack/cueparser.h b/src/plugins/Input/wavpack/cueparser.h
index a4b65dc11..2437065cf 100644
--- a/src/plugins/Input/wavpack/cueparser.h
+++ b/src/plugins/Input/wavpack/cueparser.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2008-2009 by Ilya Kotov *
+ * Copyright (C) 2008-2011 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -22,10 +22,10 @@
#include <QList>
#include <QMap>
-#include <QByteArray>
#include <QString>
#include <QStringList>
-
+#include <QUrl>
+#include <qmmp/qmmp.h>
#include <qmmp/fileinfo.h>
@@ -46,13 +46,21 @@ public:
int count() const;
FileInfo *info(int track);
const QString trackURL(int track) const;
+ const QMap<Qmmp::ReplayGainKey, double> replayGain(int track) const;
private:
- QString m_filePath;
- QList <FileInfo> m_infoList;
- QList <qint64> m_offsets;
+ struct CUETrack
+ {
+ FileInfo info;
+ qint64 offset;
+ QMap<Qmmp::ReplayGainKey, double> replayGain;
+ };
+ QList <CUETrack * > m_tracks;
+ bool m_dirty;
QStringList splitLine(const QString &line);
qint64 getLength(const QString &str);
+ QString getDirtyPath(const QString &cue, const QString &path);
+ QString m_filePath;
};
#endif
diff --git a/src/plugins/Input/wavpack/decoder_wavpack.cpp b/src/plugins/Input/wavpack/decoder_wavpack.cpp
index 3f410b6f7..437d603a7 100644
--- a/src/plugins/Input/wavpack/decoder_wavpack.cpp
+++ b/src/plugins/Input/wavpack/decoder_wavpack.cpp
@@ -127,6 +127,7 @@ bool DecoderWavPack::initialize()
length_in_bytes = audioParameters().sampleRate() *
audioParameters().channels() *
audioParameters().sampleSize() * m_length/1000;
+ setReplayGainInfo(m_parser->replayGain(m_track));
seek(0);
}
m_totalBytes = 0;
@@ -241,6 +242,7 @@ void DecoderWavPack::next()
audioParameters().channels() *
audioParameters().sampleSize() * m_length/1000;
addMetaData(m_parser->info(m_track)->metaData());
+ setReplayGainInfo(m_parser->replayGain(m_track));
m_totalBytes = 0;
}
}