diff options
Diffstat (limited to 'src/plugins/Input/wavpack')
| -rw-r--r-- | src/plugins/Input/wavpack/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/plugins/Input/wavpack/cueparser.cpp | 219 | ||||
| -rw-r--r-- | src/plugins/Input/wavpack/cueparser.h | 63 | ||||
| -rw-r--r-- | src/plugins/Input/wavpack/decoder_wavpack.cpp | 23 | ||||
| -rw-r--r-- | src/plugins/Input/wavpack/decoder_wavpack.h | 4 | ||||
| -rw-r--r-- | src/plugins/Input/wavpack/decoderwavpackfactory.cpp | 100 | ||||
| -rw-r--r-- | src/plugins/Input/wavpack/wavpack.pro | 2 | ||||
| -rw-r--r-- | src/plugins/Input/wavpack/wavpackmetadatamodel.cpp | 11 |
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; |
