aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Input/wavpack
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Input/wavpack')
-rw-r--r--src/plugins/Input/wavpack/CMakeLists.txt2
-rw-r--r--src/plugins/Input/wavpack/cueparser.cpp219
-rw-r--r--src/plugins/Input/wavpack/cueparser.h63
-rw-r--r--src/plugins/Input/wavpack/decoder_wavpack.cpp23
-rw-r--r--src/plugins/Input/wavpack/decoder_wavpack.h4
-rw-r--r--src/plugins/Input/wavpack/decoderwavpackfactory.cpp100
-rw-r--r--src/plugins/Input/wavpack/wavpack.pro2
-rw-r--r--src/plugins/Input/wavpack/wavpackmetadatamodel.cpp11
8 files changed, 68 insertions, 356 deletions
diff --git a/src/plugins/Input/wavpack/CMakeLists.txt b/src/plugins/Input/wavpack/CMakeLists.txt
index 670fe035a..371edd736 100644
--- a/src/plugins/Input/wavpack/CMakeLists.txt
+++ b/src/plugins/Input/wavpack/CMakeLists.txt
@@ -17,12 +17,10 @@ SET(libwavpack_SRCS
decoder_wavpack.cpp
decoderwavpackfactory.cpp
wavpackmetadatamodel.cpp
- cueparser.cpp
)
SET(libwavpack_HDRS
decoder_wavpack.h
- cueparser.h
)
SET(libwavpack_RCCS translations/translations.qrc)
diff --git a/src/plugins/Input/wavpack/cueparser.cpp b/src/plugins/Input/wavpack/cueparser.cpp
deleted file mode 100644
index 0dddc3354..000000000
--- a/src/plugins/Input/wavpack/cueparser.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2008-2019 by Ilya Kotov *
- * forkotov02@ya.ru *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
- ***************************************************************************/
-
-#include <QFile>
-#include <QDir>
-#include <QDirIterator>
-#include <QSettings>
-#include <QTextStream>
-#include <QTextCodec>
-#include <qmmp/decoder.h>
-#include <qmmp/metadatamanager.h>
-#include "cueparser.h"
-
-CUEParser::CUEParser(const QByteArray &array, const QString &path)
-{
- QString album, genre, date, comment;
- QTextStream textStream (array);
- textStream.setCodec("UTF-8");
- m_filePath = path;
- QString artist;
- double album_peak = 0.0, album_gain = 0.0;
- while (!textStream.atEnd())
- {
- QString line = textStream.readLine().trimmed();
- QStringList words = splitLine(line);
- if (words.size() < 2)
- continue;
-
- if (words[0] == "PERFORMER")
- {
- if(m_tracks.isEmpty())
- artist = words[1];
- else
- m_tracks.last()->info.setValue(Qmmp::ARTIST, words[1]);
- }
- else if (words[0] == "TITLE")
- {
- if(m_tracks.isEmpty())
- album = words[1];
- else
- m_tracks.last()->info.setValue(Qmmp::TITLE, words[1]);
- }
- else if (words[0] == "TRACK")
- {
- TrackInfo info("wvpack://" + path + QString("#%1").arg(words[1].toInt()));
- info.setValue(Qmmp::TRACK, words[1].toInt());
- info.setValue(Qmmp::ALBUM, album);
- info.setValue(Qmmp::GENRE, genre);
- info.setValue(Qmmp::YEAR, date);
- info.setValue(Qmmp::COMMENT, comment);
- info.setValue(Qmmp::ARTIST, artist);
- info.setValue(Qmmp::ALBUMARTIST, artist);
- info.setValue(Qmmp::REPLAYGAIN_ALBUM_GAIN, album_gain);
- info.setValue(Qmmp::REPLAYGAIN_ALBUM_PEAK, album_peak);
-
- m_tracks << new CUETrack;
- m_tracks.last()->info = info;
- m_tracks.last()->offset = 0;
- }
- else if (words[0] == "INDEX" && words[1] == "01")
- {
- if (m_tracks.isEmpty())
- continue;
- m_tracks.last()->offset = getLength(words[2]);
- int c = m_tracks.count();
- if(c > 1)
- m_tracks[c - 2]->info.setDuration(m_tracks[c - 1]->offset - m_tracks[c - 2]->offset);
- }
- else if (words[0] == "REM")
- {
- if (words.size() < 3)
- continue;
- if (words[1] == "GENRE")
- genre = words[2];
- else if (words[1] == "DATE")
- 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()->info.setValue(Qmmp::REPLAYGAIN_TRACK_GAIN, words[2].toDouble());
- else if (words[1] == "REPLAYGAIN_TRACK_PEAK" && !m_tracks.isEmpty())
- m_tracks.last()->info.setValue(Qmmp::REPLAYGAIN_TRACK_PEAK, words[2].toDouble());
- }
- }
- if(m_tracks.isEmpty())
- {
- qWarning("CUEParser: invalid cue file");
- return;
- }
-
- QList<TrackInfo *> f_list = MetaDataManager::instance()->createPlayList(m_filePath, TrackInfo::Properties);
- if(!f_list.isEmpty())
- {
- //calculate last item length
- m_tracks.last()->info.setDuration(qMax(0LL, f_list.first()->duration() - m_tracks.last()->offset));
- //add properties
- foreach(CUETrack *cueTrack, m_tracks)
- cueTrack->info.setValues(f_list.first()->properties());
- qDeleteAll(f_list);
- f_list.clear();
- }
-}
-
-CUEParser::~CUEParser()
-{
- qDeleteAll(m_tracks);
- m_tracks.clear();
-}
-
-QList<TrackInfo*> CUEParser::createPlayList()
-{
- QList<TrackInfo*> list;
- foreach(CUETrack *track, m_tracks)
- {
- list << new TrackInfo(track->info);
- }
- return list;
-}
-
-const QString CUEParser::filePath() const
-{
- return m_filePath;
-}
-
-qint64 CUEParser::offset(int track) const
-{
- return m_tracks.at(track - 1)->offset;
-}
-
-qint64 CUEParser::duration(int track) const
-{
- return m_tracks.at(track - 1)->info.duration();
-}
-
-int CUEParser::count() const
-{
- return m_tracks.count();
-}
-
-TrackInfo *CUEParser::info(int track)
-{
- return &m_tracks.at(track - 1)->info;
-}
-
-const QString CUEParser::trackURL(int track) const
-{
- return m_tracks.at(track - 1)->info.path();
-}
-
-const QMap<Qmmp::ReplayGainKey, double> CUEParser::replayGain(int track) const
-{
- return m_tracks.at(track - 1)->info.replayGainInfo();
-}
-
-QStringList CUEParser::splitLine(const QString &line)
-{
- //qDebug("raw string = %s",qPrintable(line));
- QStringList list;
- QString buf = line.trimmed();
- if (buf.isEmpty())
- return list;
- while (!buf.isEmpty())
- {
- //qDebug(qPrintable(buf));
- if (buf.startsWith('"'))
- {
- int end = buf.indexOf('"',1);
- if(end == -1) //ignore invalid line
- {
- list.clear();
- qWarning("CUEParser: unable to parse line: %s",qPrintable(line));
- return list;
- }
- list << buf.mid (1, end - 1);
- buf.remove (0, end+1);
- }
- else
- {
- int end = buf.indexOf(' ', 0);
- if (end < 0)
- end = buf.size();
- list << buf.mid (0, end);
- buf.remove (0, end);
- }
- buf = buf.trimmed();
- }
- return list;
-}
-
-qint64 CUEParser::getLength(const QString &str)
-{
- QStringList list = str.split(":");
- if (list.size() == 2)
- return (qint64)list.at(0).toInt()*60000 + list.at(1).toInt()*1000;
- else if (list.size() == 3)
- return (qint64)list.at(0).toInt()*60000 + list.at(1).toInt()*1000 + list.at(2).toInt()*1000/75;
- return 0;
-}
diff --git a/src/plugins/Input/wavpack/cueparser.h b/src/plugins/Input/wavpack/cueparser.h
deleted file mode 100644
index 12b2e7893..000000000
--- a/src/plugins/Input/wavpack/cueparser.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2008-2019 by Ilya Kotov *
- * forkotov02@ya.ru *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
- ***************************************************************************/
-#ifndef CUEPARSER_H
-#define CUEPARSER_H
-
-#include <QList>
-#include <QMap>
-#include <QString>
-#include <QStringList>
-#include <QUrl>
-#include <qmmp/qmmp.h>
-#include <qmmp/trackinfo.h>
-
-
-/**
- @author Ilya Kotov <forkotov02@ya.ru>
-*/
-class CUEParser
-{
-public:
- CUEParser(const QByteArray &array, const QString &path);
-
- ~CUEParser();
-
- QList<TrackInfo *> createPlayList();
- const QString filePath() const;
- qint64 offset(int track) const;
- qint64 duration(int track) const;
- int count() const;
- TrackInfo *info(int track);
- const QString trackURL(int track) const;
- const QMap<Qmmp::ReplayGainKey, double> replayGain(int track) const;
-
-private:
- struct CUETrack
- {
- TrackInfo info;
- qint64 offset;
- };
- QList <CUETrack *> m_tracks;
- QStringList splitLine(const QString &line);
- qint64 getLength(const QString &str);
- QString m_filePath;
-};
-
-#endif
diff --git a/src/plugins/Input/wavpack/decoder_wavpack.cpp b/src/plugins/Input/wavpack/decoder_wavpack.cpp
index a9daaf20a..0c75cb914 100644
--- a/src/plugins/Input/wavpack/decoder_wavpack.cpp
+++ b/src/plugins/Input/wavpack/decoder_wavpack.cpp
@@ -24,8 +24,8 @@
#include <QRegExp>
#include <math.h>
#include <stdint.h>
+#include <qmmp/cueparser.h>
#include <qmmp/buffer.h>
-#include <qmmp/output.h>
#include <stdlib.h>
#include "decoder_wavpack.h"
#include "cueparser.h"
@@ -62,7 +62,7 @@ bool DecoderWavPack::initialize()
m_chan = 0;
m_totalTime = 0;
- char err [80];
+ char err[80] = { 0 };
if (m_path.startsWith("wvpack://")) //embeded cue track
{
QString p = m_path;
@@ -80,14 +80,15 @@ bool DecoderWavPack::initialize()
return false;
}
int cue_len = WavpackGetTagItem (m_context, "cuesheet", nullptr, 0);
- char *value;
- if (cue_len)
+ if (cue_len > 0)
{
- value = (char*)malloc (cue_len * 2 + 1);
- WavpackGetTagItem (m_context, "cuesheet", value, cue_len + 1);
- m_parser = new CUEParser(value, p);
+ char *value = (char*)malloc (cue_len * 2 + 1);
+ WavpackGetTagItem(m_context, "cuesheet", value, cue_len + 1);
+ m_parser = new CueParser(value);
+ m_parser->setDuration((qint64)WavpackGetNumSamples(m_context) * 1000 / WavpackGetSampleRate(m_context));
+ m_parser->setUrl("wvpack", p);
m_track = m_path.section("#", -1).toInt();
- if(m_track > m_parser->count())
+ if(m_track < 1 || m_track > m_parser->count())
{
qWarning("DecoderWavPack: invalid cuesheet comment");
return false;
@@ -155,7 +156,7 @@ bool DecoderWavPack::initialize()
m_offset = m_parser->offset(m_track);
m_length_in_bytes = audioParameters().sampleRate() *
audioParameters().frameSize() * m_length/1000;
- setReplayGainInfo(m_parser->replayGain(m_track));
+ setReplayGainInfo(m_parser->info(m_track)->replayGainInfo());
seek(0);
}
m_totalBytes = 0;
@@ -218,7 +219,7 @@ qint64 DecoderWavPack::read(unsigned char *data, qint64 size)
const QString DecoderWavPack::nextURL() const
{
if(m_parser && m_track +1 <= m_parser->count())
- return m_parser->trackURL(m_track + 1);
+ return m_parser->url(m_track + 1);
else
return QString();
}
@@ -234,7 +235,7 @@ void DecoderWavPack::next()
audioParameters().channels() *
audioParameters().sampleSize() * m_length/1000;
addMetaData(m_parser->info(m_track)->metaData());
- setReplayGainInfo(m_parser->replayGain(m_track));
+ setReplayGainInfo(m_parser->info(m_track)->replayGainInfo());
m_totalBytes = 0;
}
}
diff --git a/src/plugins/Input/wavpack/decoder_wavpack.h b/src/plugins/Input/wavpack/decoder_wavpack.h
index c4f937478..ede01d1e8 100644
--- a/src/plugins/Input/wavpack/decoder_wavpack.h
+++ b/src/plugins/Input/wavpack/decoder_wavpack.h
@@ -26,7 +26,7 @@ extern "C"{
}
#include <qmmp/decoder.h>
-class CUEParser;
+class CueParser;
class DecoderWavPack : public Decoder
{
@@ -57,7 +57,7 @@ private:
qint64 m_offset;
qint64 m_length;
QString m_path;
- CUEParser *m_parser;
+ CueParser *m_parser;
int m_track;
int m_bps;
qint64 m_frame_size; //frame size
diff --git a/src/plugins/Input/wavpack/decoderwavpackfactory.cpp b/src/plugins/Input/wavpack/decoderwavpackfactory.cpp
index 3c4b8e1bd..3b6944bcf 100644
--- a/src/plugins/Input/wavpack/decoderwavpackfactory.cpp
+++ b/src/plugins/Input/wavpack/decoderwavpackfactory.cpp
@@ -19,10 +19,11 @@
***************************************************************************/
#include <QMessageBox>
+#include <QFileInfo>
+#include <qmmp/cueparser.h>
#include "wavpackmetadatamodel.h"
#include "decoder_wavpack.h"
#include "decoderwavpackfactory.h"
-#include "cueparser.h"
// DecoderWavPackFactory
bool DecoderWavPackFactory::canDecode(QIODevice *input) const
@@ -37,7 +38,7 @@ DecoderProperties DecoderWavPackFactory::properties() const
properties.name = tr("WavPack Plugin");
properties.filters << "*.wv";
properties.description = tr("WavPack Files");
- //properties.contentType = ;
+ properties.contentTypes << "audio/x-wavpack";
properties.shortName = "wavpack";
properties.hasAbout = true;
properties.hasSettings = false;
@@ -53,38 +54,31 @@ Decoder *DecoderWavPackFactory::create(const QString &p, QIODevice *)
QList<TrackInfo *> DecoderWavPackFactory::createPlayList(const QString &path, TrackInfo::Parts parts, QStringList *ignoredFiles)
{
- //extract metadata of one cue track
- if(path.contains("://"))
+ Q_UNUSED(ignoredFiles);
+
+ int track = -1; //cue track
+ QString filePath = path;
+
+ if(path.contains("://")) //is it cue track?
{
- QString filePath = path;
filePath.remove("wvpack://");
filePath.remove(QRegExp("#\\d+$"));
- int track = filePath.section("#", -1).toInt();
- QList<TrackInfo *> list = createPlayList(filePath, parts, ignoredFiles);
- if (list.isEmpty() || track <= 0 || track > list.count())
- {
- qDeleteAll(list);
- list.clear();
- return list;
- }
- TrackInfo *info = list.takeAt(track - 1);
- qDeleteAll(list);
- return QList<TrackInfo *>() << info;
+ track = path.section("#", -1).toInt();
+ parts = TrackInfo::AllParts; //extract all metadata for single cue track
}
- TrackInfo *info = new TrackInfo(path);
+ TrackInfo *info = new TrackInfo(filePath);
if(parts == TrackInfo::NoParts)
return QList<TrackInfo *>() << info;
- char err[80];
- int cue_len = 0;
+ char err[80] = { 0 };
#if defined(Q_OS_WIN) && defined(OPEN_FILE_UTF8)
- WavpackContext *ctx = WavpackOpenFileInput (path.toUtf8().constData(),
+ WavpackContext *ctx = WavpackOpenFileInput (filePath.toUtf8().constData(),
err, OPEN_WVC | OPEN_TAGS | OPEN_FILE_UTF8, 0);
#else
- WavpackContext *ctx = WavpackOpenFileInput (path.toLocal8Bit().constData(),
+ WavpackContext *ctx = WavpackOpenFileInput (filePath.toLocal8Bit().constData(),
err, OPEN_WVC | OPEN_TAGS, 0);
#endif
if (!ctx)
@@ -94,18 +88,47 @@ QList<TrackInfo *> DecoderWavPackFactory::createPlayList(const QString &path, Tr
return QList<TrackInfo *>();
}
+ if(parts & TrackInfo::Properties)
+ {
+ info->setValue(Qmmp::BITRATE, WavpackGetAverageBitrate(ctx, 1));
+ info->setValue(Qmmp::SAMPLERATE, WavpackGetSampleRate(ctx));
+ info->setValue(Qmmp::CHANNELS, WavpackGetNumChannels(ctx));
+ info->setValue(Qmmp::BITS_PER_SAMPLE, WavpackGetBitsPerSample(ctx));
+ info->setValue(Qmmp::FORMAT_NAME, "WavPack");
+ info->setValue(Qmmp::FILE_SIZE, QFileInfo(filePath).size()); //adds file size for cue tracks
+ info->setDuration((qint64)WavpackGetNumSamples(ctx) * 1000 / WavpackGetSampleRate(ctx));
+ }
+
+ if(parts & TrackInfo::ReplayGainInfo)
+ {
+ char value[200] = { 0 };
+ WavpackGetTagItem(ctx, "REPLAYGAIN_TRACK_GAIN", value, sizeof(value));
+ info->setValue(Qmmp::REPLAYGAIN_TRACK_GAIN, value);
+ WavpackGetTagItem(ctx, "REPLAYGAIN_TRACK_PEAK", value, sizeof(value));
+ info->setValue(Qmmp::REPLAYGAIN_TRACK_PEAK, value);
+ WavpackGetTagItem(ctx, "REPLAYGAIN_ALBUM_GAIN", value, sizeof(value));
+ info->setValue(Qmmp::REPLAYGAIN_ALBUM_GAIN, value);
+ WavpackGetTagItem(ctx, "REPLAYGAIN_ALBUM_PEAK", value, sizeof(value));
+ info->setValue(Qmmp::REPLAYGAIN_ALBUM_PEAK, value);
+ }
+
if(parts & TrackInfo::MetaData)
{
- cue_len = WavpackGetTagItem (ctx, "cuesheet", nullptr, 0);
- if (cue_len)
+ int cue_len = WavpackGetTagItem (ctx, "cuesheet", nullptr, 0);
+ if(cue_len > 0)
{
- delete info;
- char value[cue_len + 1];
+ char value[cue_len + 1] = { 0 };
memset(value, 0, cue_len + 1);
WavpackGetTagItem(ctx, "cuesheet", value, cue_len + 1);
+
+ CueParser parser(value);
+ parser.setDuration((qint64)WavpackGetNumSamples(ctx) * 1000 / WavpackGetSampleRate(ctx));
+ parser.setProperties(info->properties());
+ parser.setUrl("wvpack", filePath);
+
WavpackCloseFile(ctx);
- CUEParser parser(value, path);
- return parser.createPlayList();
+ delete info;
+ return (track > 0) ? parser.createPlayList(track) : parser.createPlayList();
}
else
{
@@ -133,29 +156,6 @@ QList<TrackInfo *> DecoderWavPackFactory::createPlayList(const QString &path, Tr
}
}
- if(parts & TrackInfo::Properties)
- {
- info->setValue(Qmmp::BITRATE, WavpackGetAverageBitrate(ctx, 1));
- info->setValue(Qmmp::SAMPLERATE, WavpackGetSampleRate(ctx));
- info->setValue(Qmmp::CHANNELS, WavpackGetNumChannels(ctx));
- info->setValue(Qmmp::BITS_PER_SAMPLE, WavpackGetBitsPerSample(ctx));
- info->setValue(Qmmp::FORMAT_NAME, "WavPack");
- info->setDuration((qint64)WavpackGetNumSamples(ctx) * 1000 / WavpackGetSampleRate(ctx));
- }
-
- if(parts & TrackInfo::ReplayGainInfo)
- {
- char value[200] = { 0 };
- WavpackGetTagItem(ctx, "REPLAYGAIN_TRACK_GAIN", value, sizeof(value));
- info->setValue(Qmmp::REPLAYGAIN_TRACK_GAIN, value);
- WavpackGetTagItem(ctx, "REPLAYGAIN_TRACK_PEAK", value, sizeof(value));
- info->setValue(Qmmp::REPLAYGAIN_TRACK_PEAK, value);
- WavpackGetTagItem(ctx, "REPLAYGAIN_ALBUM_GAIN", value, sizeof(value));
- info->setValue(Qmmp::REPLAYGAIN_ALBUM_GAIN, value);
- WavpackGetTagItem(ctx, "REPLAYGAIN_ALBUM_PEAK", value, sizeof(value));
- info->setValue(Qmmp::REPLAYGAIN_ALBUM_PEAK, value);
- }
-
WavpackCloseFile (ctx);
return QList<TrackInfo *>() << info;
}
diff --git a/src/plugins/Input/wavpack/wavpack.pro b/src/plugins/Input/wavpack/wavpack.pro
index d08d4141c..768cf5f2d 100644
--- a/src/plugins/Input/wavpack/wavpack.pro
+++ b/src/plugins/Input/wavpack/wavpack.pro
@@ -4,12 +4,10 @@ TARGET = $$PLUGINS_PREFIX/Input/wavpack
HEADERS += decoderwavpackfactory.h \
decoder_wavpack.h \
- cueparser.h \
wavpackmetadatamodel.h
SOURCES += decoder_wavpack.cpp \
decoderwavpackfactory.cpp \
- cueparser.cpp \
wavpackmetadatamodel.cpp
diff --git a/src/plugins/Input/wavpack/wavpackmetadatamodel.cpp b/src/plugins/Input/wavpack/wavpackmetadatamodel.cpp
index 53d1d798a..117ce4b1b 100644
--- a/src/plugins/Input/wavpack/wavpackmetadatamodel.cpp
+++ b/src/plugins/Input/wavpack/wavpackmetadatamodel.cpp
@@ -25,15 +25,12 @@
WavPackMetaDataModel::WavPackMetaDataModel(const QString &path, bool readOnly)
: MetaDataModel(readOnly)
{
- if(path.contains("://"))
+ m_path = path;
+ if(m_path.contains("://"))
{
- QString p = path;
- p.remove("wvpack://");
- p.remove(QRegExp("#\\d+$"));
- m_path = p;
+ m_path.remove("wvpack://");
+ m_path.remove(QRegExp("#\\d+$"));
}
- else
- m_path = path;
char err[80] = {0};
int flags = OPEN_WVC | OPEN_TAGS;