diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2008-10-10 08:42:15 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2008-10-10 08:42:15 +0000 |
| commit | 45117f6d2f2ccfb47af840d4416f43607d83d518 (patch) | |
| tree | ee3e2b99914fa6907ce7e1173e1fc87575fe8a37 | |
| parent | 0bb73fcbfda56e4cb064a7bc1ceda89312087f3d (diff) | |
| download | qmmp-45117f6d2f2ccfb47af840d4416f43607d83d518.tar.gz qmmp-45117f6d2f2ccfb47af840d4416f43607d83d518.tar.bz2 qmmp-45117f6d2f2ccfb47af840d4416f43607d83d518.zip | |
cue sheet support
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@575 90c681e8-e032-0410-971d-27865f9a5e38
33 files changed, 962 insertions, 119 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e5300d19..1f330e4cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ PRINT_SUMMARY ("MOD support ......................." USE_MODPLUG MODPLUG_FOUND) PRINT_SUMMARY ("Wave support ......................" USE_SNDFILE SNDFILE_FOUND) PRINT_SUMMARY ("WavPack support ..................." USE_WAVPACK WAVPACK_FOUND) PRINT_SUMMARY ("WMA support ......................." USE_FFMPEG FFMPEG_FOUND) +PRINT_SUMMARY ("CUE sheet support ................." USE_CUE 1) MESSAGE("") MESSAGE("Output Plugins:") diff --git a/src/plugins/Input/CMakeLists.txt b/src/plugins/Input/CMakeLists.txt index 7a68dd8a3..3222be482 100644 --- a/src/plugins/Input/CMakeLists.txt +++ b/src/plugins/Input/CMakeLists.txt @@ -9,6 +9,7 @@ SET(USE_MPC TRUE CACHE BOOL "enable/disable mpc plugin") SET(USE_SNDFILE TRUE CACHE BOOL "enable/disable sndfile plugin") SET(USE_WAVPACK TRUE CACHE BOOL "enable/disable wavpack plugin") SET(USE_MODPLUG TRUE CACHE BOOL "enable/disable modplug plugin") +SET(USE_CUE TRUE CACHE BOOL "enable/disable cue plugin") pkg_check_modules(TAGLIB taglib) @@ -43,3 +44,7 @@ ENDIF(USE_WAVPACK) IF(USE_MODPLUG) #add_subdirectory(modplug) ENDIF(USE_MODPLUG) + +IF(USE_CUE) +add_subdirectory(cue) +ENDIF(USE_CUE) diff --git a/src/plugins/Input/Input.pro b/src/plugins/Input/Input.pro index 1035f6484..e40e324cd 100644 --- a/src/plugins/Input/Input.pro +++ b/src/plugins/Input/Input.pro @@ -1,6 +1,6 @@ include(../../../qmmp.pri) -SUBDIRS += mad vorbis # sndfile wavpack +SUBDIRS += mad vorbis cue # sndfile wavpack TEMPLATE = subdirs contains(CONFIG, MODPLUG_PLUGIN){ diff --git a/src/plugins/Input/cue/CMakeLists.txt b/src/plugins/Input/cue/CMakeLists.txt new file mode 100644 index 000000000..b27497e1f --- /dev/null +++ b/src/plugins/Input/cue/CMakeLists.txt @@ -0,0 +1,66 @@ +project(libcue) + +cmake_minimum_required(VERSION 2.4.7) + +if(COMMAND cmake_policy) +cmake_policy(SET CMP0003 NEW) +endif(COMMAND cmake_policy) + + +# qt plugin +ADD_DEFINITIONS( -Wall ) +ADD_DEFINITIONS(${QT_DEFINITIONS}) +ADD_DEFINITIONS(-DQT_PLUGIN) +ADD_DEFINITIONS(-DQT_NO_DEBUG) +ADD_DEFINITIONS(-DQT_SHARED) +ADD_DEFINITIONS(-DQT_THREAD) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +SET(QT_INCLUDES + ${QT_INCLUDES} + ${CMAKE_CURRENT_BINARY_DIR}/../../../ +) + +# libqmmp +include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../) +link_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../qmmp) + + +SET(libcue_SRCS + decoder_cue.cpp + decodercuefactory.cpp +# detailsdialog.cpp + cueparser.cpp +) + +SET(libcue_MOC_HDRS + decodercuefactory.h + decoder_cue.h +# detailsdialog.h + cueparser.h +) + +#SET(libcue_RCCS translations/translations.qrc) + +QT4_ADD_RESOURCES(libcue_RCC_SRCS ${libcue_RCCS}) + +QT4_WRAP_CPP(libcue_MOC_SRCS ${libcue_MOC_HDRS}) + +# user interface + + +#SET(libcue_UIS +# detailsdialog.ui +#) + +#QT4_WRAP_UI(libcue_UIS_H ${libcue_UIS}) +# Don't forget to include output directory, otherwise +# the UI file won't be wrapped! +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +ADD_LIBRARY(cue SHARED ${libcue_SRCS} ${libcue_MOC_SRCS} ${libcue_RCC_SRCS}) +add_dependencies(cue qmmp) +target_link_libraries(cue ${QT_LIBRARIES} -lqmmp) +install(TARGETS cue DESTINATION ${LIB_DIR}/qmmp/Input) + diff --git a/src/plugins/Input/cue/cue.pro b/src/plugins/Input/cue/cue.pro new file mode 100644 index 000000000..1c0771d5c --- /dev/null +++ b/src/plugins/Input/cue/cue.pro @@ -0,0 +1,36 @@ +include(../../plugins.pri) + +#FORMS += detailsdialog.ui +HEADERS += decodercuefactory.h \ + cueparser.h \ + decoder_cue.h +SOURCES += decoder_cue.cpp \ + decodercuefactory.cpp \ + cueparser.cpp + +TARGET =$$PLUGINS_PREFIX/Input/cue +QMAKE_CLEAN =$$PLUGINS_PREFIX/Input/libcue.so + +INCLUDEPATH += ../../../ +CONFIG += release \ +warn_on \ +plugin + +TEMPLATE = lib + +QMAKE_LIBDIR += ../../../../lib +LIBS += -lqmmp -L/usr/lib + +#TRANSLATIONS = translations/cue_plugin_ru.ts +# translations/cue_plugin_uk_UA.ts +# translations/cue_plugin_zh_CN.ts +# translations/cue_plugin_zh_TW.ts +# translations/cue_plugin_cs.ts +# translations/cue_plugin_de.ts +#RESOURCES = translations/translations.qrc + +isEmpty(LIB_DIR){ + LIB_DIR = /lib +} +target.path = $$LIB_DIR/qmmp/Input +INSTALLS += target diff --git a/src/plugins/Input/cue/cueparser.cpp b/src/plugins/Input/cue/cueparser.cpp new file mode 100644 index 000000000..cf79db5c2 --- /dev/null +++ b/src/plugins/Input/cue/cueparser.cpp @@ -0,0 +1,173 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ilya Kotov * + * forkotov02@hotmail.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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <QFile> +#include <QFileInfo> +#include <QRegExp> +#include <QDir> + +#include <qmmp/decoder.h> + +#include "cueparser.h" + +CUEParser::CUEParser(const QString &fileName) +{ + QString album; + QFile file(fileName); + file.open(QIODevice::ReadOnly); + + while (!file.atEnd()) + { + QString line = file.readLine().trimmed(); + QStringList words = splitLine(line); + if (words.size() < 2) + continue; + + if (words[0] == "FILE") + { + //TODO check support + m_filePath = QUrl(fileName).path (); + m_filePath = QFileInfo(m_filePath).dir().filePath(words[1]); + } + else if (words[0] == "PERFORMER") + { + if (m_infoList.isEmpty()) + continue; + else + m_infoList.last().setMetaData(Qmmp::ARTIST, words[1]); + + } + else if (words[0] == "TITLE") + { + if (m_infoList.isEmpty()) + album = words[1]; + else + m_infoList.last().setMetaData(Qmmp::TITLE, words[1]); + } + else if (words[0] == "TRACK") + { + FileInfo info("cue://" + fileName + QString("#%1").arg(words[1].toInt())); + info.setMetaData(Qmmp::TRACK, words[1].toInt()); + m_infoList << info; + m_offsets << 0; + } + else if (words[0] == "INDEX") + { + if (m_infoList.isEmpty()) + continue; + m_infoList.last ().setLength(getLength(words[2])); + m_offsets.last() = getLength(words[2]); + } + } + //calculate length + for (int i = 0; i < m_infoList.size() - 1; ++i) + m_infoList[i].setLength(m_infoList[i+1].length()-m_infoList[i].length()); + //calculate last item length + QList <FileInfo *> f_list; + f_list = Decoder::createPlayList(m_filePath); + qint64 l = f_list.isEmpty() ? 0 : f_list.at(0)->length(); + if (l > m_infoList.last().length()) + m_infoList.last().setLength(l - m_infoList.last().length()); + else + m_infoList.last().setLength(0); + + foreach(FileInfo info, m_infoList) + { + info.setMetaData(Qmmp::ALBUM, album); + } + file.close(); +} + + +CUEParser::~CUEParser() +{ +} + +QList<FileInfo*> CUEParser::createPlayList() +{ + QList<FileInfo*> list; + foreach(FileInfo info, m_infoList) + { + list << new FileInfo(info); + } + return list; +} + +const QString CUEParser::filePath() +{ + return m_filePath; +} + +qint64 CUEParser::offset(int track) +{ + return m_offsets.at(track - 1); +} + +qint64 CUEParser::length(int track) +{ + return m_infoList.at(track - 1).length(); +} + +int CUEParser::count() +{ + return m_infoList.count(); +} + +FileInfo *CUEParser::info(int track) +{ + return &m_infoList[track - 1]; +} + +QStringList CUEParser::splitLine(const QString &line) +{ + //qDebug("row 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); + 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; +} + +int CUEParser::getLength(const QString &str) +{ + QStringList list = str.split(":"); + if (list.size() < 2) + return 0; + return list.at(0).toInt()*60 + list.at(1).toInt(); +} diff --git a/src/plugins/Input/cue/cueparser.h b/src/plugins/Input/cue/cueparser.h new file mode 100644 index 000000000..61807319a --- /dev/null +++ b/src/plugins/Input/cue/cueparser.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ilya Kotov * + * forkotov02@hotmail.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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef CUEPARSER_H +#define CUEPARSER_H + +#include <QList> +#include <QMap> +#include <QString> +#include <QStringList> + +#include <qmmp/fileinfo.h> + + +/** + @author Ilya Kotov <forkotov02@hotmail.ru> +*/ +class CUEParser{ +public: + CUEParser(const QString &fileName); + + ~CUEParser(); + + QList<FileInfo*> createPlayList(); + const QString filePath(); + qint64 offset(int track); + qint64 length(int track); + int count(); + FileInfo *info(int track); + +private: + QList< QMap<int, int> > m_map; + QString m_filePath; + QList <FileInfo> m_infoList; + QList <int> m_offsets; + QStringList splitLine(const QString &line); + int getLength(const QString &str); + +}; + +#endif diff --git a/src/plugins/Input/cue/decoder_cue.cpp b/src/plugins/Input/cue/decoder_cue.cpp new file mode 100644 index 000000000..d988d9aba --- /dev/null +++ b/src/plugins/Input/cue/decoder_cue.cpp @@ -0,0 +1,208 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ilya Kotov * + * forkotov02@hotmail.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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <qmmp/constants.h> +#include <qmmp/buffer.h> +#include <qmmp/output.h> +#include <qmmp/recycler.h> +#include <qmmp/fileinfo.h> +#include <qmmp/decoderfactory.h> + +#include <QObject> +#include <QFile> + +#include "cueparser.h" +#include "decoder_cue.h" + + +DecoderCUE::DecoderCUE(QObject *parent, DecoderFactory *d, const QString &url) + : Decoder(parent, d) +{ + path = url; + m_decoder = 0; + m_output2 = 0; + m_input2 = 0; +} + +DecoderCUE::~DecoderCUE() +{} + +bool DecoderCUE::initialize() +{ + CUEParser parser(QUrl(path).path()); + int track = path.section("#", -1).toInt(); + path = parser.filePath(); + DecoderFactory *df = Decoder::findByPath(path); + if (df) + { + m_input2 = new QFile(path); + if (!m_input2->open(QIODevice::ReadOnly)) + { + qDebug("DecoderCUE: cannot open input"); + stop(); + //m_handler->dispatch(Qmmp::NormalError); + return FALSE; + } + } + if (!df->properties().noOutput) + { + m_output2 = Output::create(this); + if (!m_output2) + { + qWarning("DecoderCUE: unable to create output"); + //m_handler->dispatch(Qmmp::FatalError); + return FALSE; + } + if (!m_output2->initialize()) + { + qWarning("SoundCore: unable to initialize output"); + delete m_output2; + m_output2 = 0; + //m_handler->dispatch(Qmmp::FatalError); + return FALSE; + } + } + m_length = parser.length(track); + m_offset = parser.offset(track); + m_decoder = df->create(this, m_input2, m_output2, path); + CUEStateHandler *csh = new CUEStateHandler(this, m_offset, m_length); + m_decoder->setStateHandler(csh); + connect(csh, SIGNAL(finished()), SLOT(finish())); + connect(m_decoder, SIGNAL(playbackFinished()), SLOT(finish())); + if (m_output2) + m_output2->setStateHandler(m_decoder->stateHandler()); + m_decoder->initialize(); + m_decoder->seek(parser.offset(track)); + if (m_output2) + m_output2->seek(parser.offset(track)); + + //send metadata + QMap<Qmmp::MetaData, QString> metaData = parser.info(track)->metaData(); + StateHandler::instance()->dispatch(metaData); + return TRUE; +} + +qint64 DecoderCUE::lengthInSeconds() +{ + return m_decoder ? m_length : 0; +} + +void DecoderCUE::seek(qint64 pos) +{ + if (m_output2 && m_output2->isRunning()) + { + m_output2->mutex()->lock (); + m_output2->seek(m_offset + pos); + m_output2->mutex()->unlock(); + if (m_decoder && m_decoder->isRunning()) + { + m_decoder->mutex()->lock (); + m_decoder->seek(m_offset + pos); + m_decoder->mutex()->unlock(); + } + } + else if (m_decoder) + { + m_decoder->mutex()->lock (); + m_decoder->seek(m_offset + pos); + m_decoder->mutex()->unlock(); + } +} + +void DecoderCUE::stop() +{ + if (m_decoder /*&& m_decoder->isRunning()*/) + { + m_decoder->mutex()->lock (); + m_decoder->stop(); + m_decoder->mutex()->unlock(); + //m_decoder->stateHandler()->dispatch(Qmmp::Stopped); + } + if (m_output2) + { + m_output2->mutex()->lock (); + m_output2->stop(); + m_output2->mutex()->unlock(); + } + + // wake up threads + if (m_decoder) + { + m_decoder->mutex()->lock (); + m_decoder->cond()->wakeAll(); + m_decoder->mutex()->unlock(); + } + if (m_output2) + { + m_output2->recycler()->mutex()->lock (); + m_output2->recycler()->cond()->wakeAll(); + m_output2->recycler()->mutex()->unlock(); + } + if (m_decoder) + m_decoder->wait(); + if (m_output2) + m_output2->wait(); + + if (m_input2) + { + m_input2->deleteLater(); + m_input2 = 0; + } +} + +void DecoderCUE::run() +{ + m_decoder->start(); + if (m_output2) + m_output2->start(); +} + + +CUEStateHandler::CUEStateHandler(QObject *parent, qint64 offset, qint64 length): StateHandler(parent) +{ + m_offset = offset; + m_length2 = length; +} + +CUEStateHandler::~CUEStateHandler(){}; + +void CUEStateHandler::dispatch(qint64 elapsed, + qint64 totalTime, + int bitrate, + int frequency, + int precision, + int channels) +{ + Q_UNUSED(totalTime); + StateHandler::instance()->dispatch(elapsed - m_offset, m_length2, bitrate, + frequency, precision, channels); + if (elapsed - m_offset > m_length2) + emit finished(); +} + +void CUEStateHandler::dispatch(const QMap<Qmmp::MetaData, QString> &metaData) +{ + //ignore media file metadata +} + +void CUEStateHandler::dispatch(const Qmmp::State &state) +{ + StateHandler::instance()->dispatch(state); +} diff --git a/src/plugins/Input/cue/decoder_cue.h b/src/plugins/Input/cue/decoder_cue.h new file mode 100644 index 000000000..4e0775151 --- /dev/null +++ b/src/plugins/Input/cue/decoder_cue.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ilya Kotov * + * forkotov02@hotmail.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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef DECODER_CUE_H +#define DECODER_CUE_H + +#include <qmmp/decoder.h> +#include <qmmp/statehandler.h> + +class Output; +class QIDevice; +//class CUEStateHandler; + +class DecoderCUE : public Decoder +{ + Q_OBJECT +public: + DecoderCUE(QObject *, DecoderFactory *, const QString &url); + virtual ~DecoderCUE(); + + // Standard Decoder API + bool initialize(); + qint64 lengthInSeconds(); + void seek(qint64); + void stop(); + +private: + // thread run function + void run(); + QString path; + Decoder *m_decoder; + Output *m_output2; + QIODevice *m_input2; + qint64 m_length; + qint64 m_offset; +}; + +class CUEStateHandler : public StateHandler +{ + Q_OBJECT +public: + CUEStateHandler(QObject *parent, qint64 offset, qint64 length); + virtual ~CUEStateHandler(); + + void dispatch(qint64 elapsed, + qint64 totalTime, + int bitrate, + int frequency, + int precision, + int channels); + + void dispatch(const QMap<Qmmp::MetaData, QString> &metaData); + + void dispatch(const Qmmp::State &state); + +signals: + void finished(); + +private: + qint64 m_length2; + qint64 m_offset; + +}; + +#endif // DECODER_CUE_H diff --git a/src/plugins/Input/cue/decodercuefactory.cpp b/src/plugins/Input/cue/decodercuefactory.cpp new file mode 100644 index 000000000..c87c4f4a6 --- /dev/null +++ b/src/plugins/Input/cue/decodercuefactory.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ilya Kotov * + * forkotov02@hotmail.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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include <QtGui> + +#include "decoder_cue.h" +#include "cueparser.h" +#include "decodercuefactory.h" + + +// DecoderOggFactory + +bool DecoderCUEFactory::supports(const QString &source) const +{ + return source.right(4).toLower() == ".cue"; +} + +bool DecoderCUEFactory::canDecode(QIODevice *input) const +{ + return FALSE; +} + +const DecoderProperties DecoderCUEFactory::properties() const +{ + DecoderProperties properties; + properties.name = tr("CUE Plugin"); + properties.shortName = "cue"; + properties.filter = "*.cue"; + properties.description = tr("CUE Files"); + //properties.contentType = "application/ogg;audio/x-vorbis+ogg"; + properties.protocols = "cue"; + properties.hasAbout = TRUE; + properties.hasSettings = FALSE; + properties.noInput = TRUE; + properties.noOutput = TRUE; + return properties; +} + +Decoder *DecoderCUEFactory::create(QObject *parent, QIODevice *input, + Output *output, const QString &url) +{ + return new DecoderCUE(parent, this, url); +} + +//FileInfo *DecoderCUEFactory::createFileInfo(const QString &source) +QList<FileInfo *> DecoderCUEFactory::createPlayList(const QString &fileName) +{ + CUEParser parser(fileName); + return parser.createPlayList(); +} + +QObject* DecoderCUEFactory::showDetails(QWidget *parent, const QString &path) +{ + return 0; +} + +void DecoderCUEFactory::showSettings(QWidget *) +{} + +void DecoderCUEFactory::showAbout(QWidget *parent) +{ + QMessageBox::about (parent, tr("About CUE Audio Plugin"), + tr("Qmmp CUE Audio Plugin")+"\n"+ + tr("Writen by: Ilya Kotov <forkotov02@hotmail.ru>")); +} + +QTranslator *DecoderCUEFactory::createTranslator(QObject *parent) +{ + QTranslator *translator = new QTranslator(parent); + QString locale = QLocale::system().name(); + translator->load(QString(":/cue_plugin_") + locale); + return translator; +} + +Q_EXPORT_PLUGIN(DecoderCUEFactory) diff --git a/src/plugins/Input/cue/decodercuefactory.h b/src/plugins/Input/cue/decodercuefactory.h new file mode 100644 index 000000000..8cf38c6ad --- /dev/null +++ b/src/plugins/Input/cue/decodercuefactory.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2006-2008 by Ilya Kotov * + * forkotov02@hotmail.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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DECODERCUEFACTORY_H +#define DECODERCUEFACTORY_H + +#include <QObject> +#include <QString> +#include <QIODevice> +#include <QWidget> + +#include <qmmp/decoder.h> +#include <qmmp/output.h> +#include <qmmp/decoderfactory.h> +#include <qmmp/fileinfo.h> + +class DecoderCUEFactory : public QObject, DecoderFactory +{ +Q_OBJECT +Q_INTERFACES(DecoderFactory); + +public: + bool supports(const QString &source) const; + bool canDecode(QIODevice *input) const; + const DecoderProperties properties() const; + Decoder *create(QObject *, QIODevice *, Output *, const QString &); + //FileInfo *createFileInfo(const QString &source); + QList<FileInfo *> createPlayList(const QString &fileName); + QObject* showDetails(QWidget *parent, const QString &path); + void showSettings(QWidget *parent); + void showAbout(QWidget *parent); + QTranslator *createTranslator(QObject *parent); +}; + +#endif diff --git a/src/plugins/Input/ffmpeg/CMakeLists.txt b/src/plugins/Input/ffmpeg/CMakeLists.txt index a97c78bad..a65f35963 100644 --- a/src/plugins/Input/ffmpeg/CMakeLists.txt +++ b/src/plugins/Input/ffmpeg/CMakeLists.txt @@ -100,6 +100,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) IF(FFMPEG_FOUND) ADD_LIBRARY(ffmpeg SHARED ${libffmpeg_SRCS} ${libffmpeg_MOC_SRCS} ${libffmpeg_UIS_H} ${libffmpeg_RCC_SRCS}) +add_dependencies(ffmpeg qmmp) target_link_libraries(ffmpeg ${QT_LIBRARIES} -lqmmp ${FFMPEG_LDFLAGS} ${FFMPEG_CFLAGS}) install(TARGETS ffmpeg DESTINATION ${LIB_DIR}/qmmp/Input) ENDIF(FFMPEG_FOUND) diff --git a/src/plugins/Input/mad/decoder_mad.cpp b/src/plugins/Input/mad/decoder_mad.cpp index 0eeb912cf..74b7c124a 100644 --- a/src/plugins/Input/mad/decoder_mad.cpp +++ b/src/plugins/Input/mad/decoder_mad.cpp @@ -110,7 +110,7 @@ bool DecoderMAD::initialize() if (input()->isSequential ()) //for streams only { TagExtractor extractor(input()); - StateHandler::instance()->dispatch(extractor.id3v2tag()); + stateHandler()->dispatch(extractor.id3v2tag()); } mad_stream_init(&stream); diff --git a/src/plugins/Input/mad/decodermadfactory.cpp b/src/plugins/Input/mad/decodermadfactory.cpp index c41ab6fe9..ef8de8d45 100644 --- a/src/plugins/Input/mad/decodermadfactory.cpp +++ b/src/plugins/Input/mad/decodermadfactory.cpp @@ -99,11 +99,12 @@ Decoder *DecoderMADFactory::create(QObject *parent, QIODevice *input, Output *ou return new DecoderMAD(parent, this, input, output); } -FileInfo *DecoderMADFactory::createFileInfo(const QString &source) +//FileInfo *DecoderMADFactory::createFileInfo(const QString &source) +QList<FileInfo *> DecoderMADFactory::createPlayList(const QString &fileName) { - FileInfo *info = new FileInfo(); + FileInfo *info = new FileInfo(fileName); TagLib::Tag *tag = 0; - TagLib::MPEG::File fileRef(source.toLocal8Bit ()); + TagLib::MPEG::File fileRef(fileName.toLocal8Bit ()); QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat); settings.beginGroup("MAD"); @@ -183,7 +184,9 @@ FileInfo *DecoderMADFactory::createFileInfo(const QString &source) } if (fileRef.audioProperties()) info->setLength(fileRef.audioProperties()->length()); - return info; + QList <FileInfo*> list; + list << info; + return list; } QObject* DecoderMADFactory::showDetails(QWidget *parent, const QString &path) diff --git a/src/plugins/Input/mad/decodermadfactory.h b/src/plugins/Input/mad/decodermadfactory.h index b455f360e..a4d4d57ad 100644 --- a/src/plugins/Input/mad/decodermadfactory.h +++ b/src/plugins/Input/mad/decodermadfactory.h @@ -43,7 +43,8 @@ public: bool canDecode(QIODevice *input) const; const DecoderProperties properties() const; Decoder *create(QObject *, QIODevice *, Output *, const QString &); - FileInfo *createFileInfo(const QString &source); + //FileInfo *createFileInfo(const QString &source); + QList<FileInfo *> createPlayList(const QString &fileName); QObject* showDetails(QWidget *parent, const QString &path); void showSettings(QWidget *parent); void showAbout(QWidget *parent); diff --git a/src/plugins/Input/vorbis/decoder_vorbis.cpp b/src/plugins/Input/vorbis/decoder_vorbis.cpp index 2d3500559..083ae1b30 100644 --- a/src/plugins/Input/vorbis/decoder_vorbis.cpp +++ b/src/plugins/Input/vorbis/decoder_vorbis.cpp @@ -292,7 +292,7 @@ void DecoderVorbis::updateTags() + strlen ("date=")))); } - StateHandler::instance()->dispatch(metaData); + stateHandler()->dispatch(metaData); } void DecoderVorbis::run() diff --git a/src/plugins/Input/vorbis/decodervorbisfactory.cpp b/src/plugins/Input/vorbis/decodervorbisfactory.cpp index ceb0083ba..deca4f510 100644 --- a/src/plugins/Input/vorbis/decodervorbisfactory.cpp +++ b/src/plugins/Input/vorbis/decodervorbisfactory.cpp @@ -63,25 +63,26 @@ Decoder *DecoderVorbisFactory::create(QObject *parent, QIODevice *input, return new DecoderVorbis(parent, this, input, output); } -FileInfo *DecoderVorbisFactory::createFileInfo(const QString &source) +//FileInfo *DecoderVorbisFactory::createFileInfo(const QString &source) +QList<FileInfo *> DecoderVorbisFactory::createPlayList(const QString &fileName) { - FileInfo *info = new FileInfo(); + FileInfo *info = new FileInfo(fileName); - TagLib::FileRef fileRef(source.toLocal8Bit ()); + TagLib::FileRef fileRef(fileName.toLocal8Bit ()); TagLib::Tag *tag = fileRef.tag(); if (tag && !tag->isEmpty()) { info->setMetaData(Qmmp::ALBUM, - QString::fromUtf8(tag->album().toCString(TRUE)).trimmed()); + QString::fromUtf8(tag->album().toCString(TRUE)).trimmed()); info->setMetaData(Qmmp::ARTIST, - QString::fromUtf8(tag->artist().toCString(TRUE)).trimmed()); + QString::fromUtf8(tag->artist().toCString(TRUE)).trimmed()); info->setMetaData(Qmmp::COMMENT, - QString::fromUtf8(tag->comment().toCString(TRUE)).trimmed()); + QString::fromUtf8(tag->comment().toCString(TRUE)).trimmed()); info->setMetaData(Qmmp::GENRE, - QString::fromUtf8(tag->genre().toCString(TRUE)).trimmed()); + QString::fromUtf8(tag->genre().toCString(TRUE)).trimmed()); info->setMetaData(Qmmp::TITLE, - QString::fromUtf8(tag->title().toCString(TRUE)).trimmed()); + QString::fromUtf8(tag->title().toCString(TRUE)).trimmed()); info->setMetaData(Qmmp::YEAR, tag->year()); info->setMetaData(Qmmp::TRACK, tag->track()); } @@ -89,7 +90,9 @@ FileInfo *DecoderVorbisFactory::createFileInfo(const QString &source) if (fileRef.audioProperties()) info->setLength(fileRef.audioProperties()->length()); - return info; + QList <FileInfo*> list; + list << info; + return list; } QObject* DecoderVorbisFactory::showDetails(QWidget *parent, const QString &path) diff --git a/src/plugins/Input/vorbis/decodervorbisfactory.h b/src/plugins/Input/vorbis/decodervorbisfactory.h index 811f2edc4..05c1d0ea6 100644 --- a/src/plugins/Input/vorbis/decodervorbisfactory.h +++ b/src/plugins/Input/vorbis/decodervorbisfactory.h @@ -44,7 +44,8 @@ public: bool canDecode(QIODevice *input) const; const DecoderProperties properties() const; Decoder *create(QObject *, QIODevice *, Output *, const QString &); - FileInfo *createFileInfo(const QString &source); + //FileInfo *createFileInfo(const QString &source); + QList<FileInfo *> createPlayList(const QString &fileName); QObject* showDetails(QWidget *parent, const QString &path); void showSettings(QWidget *parent); void showAbout(QWidget *parent); diff --git a/src/qmmp/decoder.cpp b/src/qmmp/decoder.cpp index 25643e435..a4d739cf5 100644 --- a/src/qmmp/decoder.cpp +++ b/src/qmmp/decoder.cpp @@ -10,7 +10,6 @@ #include <QSettings> #include <math.h> - #include "effect.h" #include "effectfactory.h" @@ -21,6 +20,7 @@ #include "decoderfactory.h" #include "streamreader.h" #include "volumecontrol.h" + extern "C" { #include "equ/iir.h" @@ -32,13 +32,14 @@ Decoder::Decoder(QObject *parent, DecoderFactory *d, QIODevice *i, Output *o) : QThread(parent), m_factory(d), m_input(i), m_output(o),m_eqInited(FALSE), m_useEQ(FALSE) { - m_output->recycler()->clear(); + if (m_output) + m_output->recycler()->clear(); int b[] = {0,0,0,0,0,0,0,0,0,0}; setEQ(b, 0); qRegisterMetaType<Qmmp::State>("Qmmp::State"); blksize = Buffer::size(); m_effects = Effect::create(this); - m_handler = StateHandler::instance(); + m_handler = 0; } Decoder::~Decoder() @@ -79,6 +80,11 @@ StateHandler *Decoder::stateHandler() return m_handler; } +void Decoder::setStateHandler(StateHandler *handler) +{ + m_handler = handler; +} + void Decoder::setEQ(int bands[10], int preamp) { set_preamp(0, 1.0 + 0.0932471 *preamp + 0.00279033 * preamp * preamp); @@ -356,6 +362,8 @@ DecoderFactory *Decoder::findByContent(QIODevice *input) DecoderFactory *Decoder::findByURL(const QUrl &url) { + qDebug("url.scheme() %s", qPrintable(url.scheme())); + qDebug("url.path() = %s", qPrintable(url.path())); checkFactories(); foreach(DecoderFactory *fact, *m_factories) { @@ -400,7 +408,7 @@ bool Decoder::isEnabled(DecoderFactory* factory) return !disabledList.contains(name); } -FileInfo *Decoder::createFileInfo(const QString &fileName) +/*FileInfo *Decoder::createFileInfo(const QString &fileName) { DecoderFactory *fact = Decoder::findByPath(fileName); if (fact && QFile::exists(fileName)) @@ -411,6 +419,27 @@ FileInfo *Decoder::createFileInfo(const QString &fileName) return fact->createFileInfo(fileName); } return 0; +}*/ + +QList <FileInfo *> Decoder::createPlayList(const QString &fileName) +{ + QList <FileInfo *> list; + if (QFile::exists(fileName)) //is it file? + { + DecoderFactory *fact = Decoder::findByPath(fileName); + if (fact) + list << fact->createPlayList(fileName); + } + else + //TODO do this according supported protocols + list << new FileInfo(fileName); //create empty FileInfo for stream + //append path if it is empty + foreach(FileInfo *info, list) + { + if (info->path().isEmpty()) + info->setPath(fileName); + } + return list; } QStringList Decoder::filters() diff --git a/src/qmmp/decoder.h b/src/qmmp/decoder.h index feaa5dd85..42b2a8639 100644 --- a/src/qmmp/decoder.h +++ b/src/qmmp/decoder.h @@ -14,6 +14,7 @@ #include <QObject> #include <QStringList> #include <QUrl> +#include <QList> #include "fileinfo.h" @@ -53,6 +54,7 @@ public: QWaitCondition *cond(); StateHandler *stateHandler(); + void setStateHandler(StateHandler *handler); void setEQ(int bands[10], int preamp); void setEQEnabled(bool on); @@ -64,7 +66,9 @@ public: static DecoderFactory *findByMime(const QString&); static DecoderFactory *findByContent(QIODevice *); static DecoderFactory *findByURL(const QUrl &url); - static FileInfo *createFileInfo(const QString &fileName); + //static FileInfo *createFileInfo(const QString &fileName); + static QList <FileInfo *> createPlayList(const QString &fileName); + //static QList <FileInfo *> createPlayList(const QStringList &fileList); static QStringList filters(); static QStringList nameFilters(); static QList<DecoderFactory*> *factories(); @@ -78,6 +82,7 @@ signals: protected: void configure(quint32 srate, int chan, int bps); qint64 produceSound(char *data, qint64 size, quint32 brate, int chan); +protected slots: void finish(); private: diff --git a/src/qmmp/decoderfactory.h b/src/qmmp/decoderfactory.h index 0bfb6d0ef..80b2008ee 100644 --- a/src/qmmp/decoderfactory.h +++ b/src/qmmp/decoderfactory.h @@ -64,7 +64,8 @@ public: virtual const DecoderProperties properties() const = 0; virtual Decoder *create(QObject *, QIODevice *input = 0, Output *output = 0, const QString &path = QString()) = 0; - virtual FileInfo *createFileInfo(const QString &source) = 0; + //virtual FileInfo *createFileInfo(const QString &source) = 0; + virtual QList<FileInfo *> createPlayList(const QString &fileName) = 0; virtual QObject* showDetails(QWidget *parent, const QString &path) = 0; virtual void showSettings(QWidget *parent) = 0; virtual void showAbout(QWidget *parent) = 0; diff --git a/src/qmmp/fileinfo.cpp b/src/qmmp/fileinfo.cpp index 055cec343..593b5203c 100644 --- a/src/qmmp/fileinfo.cpp +++ b/src/qmmp/fileinfo.cpp @@ -19,10 +19,10 @@ ***************************************************************************/ #include "fileinfo.h" -FileInfo::FileInfo() +FileInfo::FileInfo(const QString &path) { + m_path = path; m_length = 0; - m_count = 1; } FileInfo::FileInfo(const FileInfo &other) @@ -37,14 +37,14 @@ void FileInfo::operator=(const FileInfo &info) { setLength(info.length()); setMetaData(info.metaData()); - setUrl(info.url()); + setPath(info.path()); } bool FileInfo::operator==(const FileInfo &info) { return metaData () == info.metaData () && length () == info.length (); - url() == info.url(); + path() == info.path(); } bool FileInfo::operator!=(const FileInfo &info) @@ -77,9 +77,9 @@ bool FileInfo::isEmpty() const return m_metaData.isEmpty(); //TODO add correct test } -const QUrl FileInfo::url() const +const QString FileInfo::path() const { - return m_url; + return m_path; } void FileInfo::setLength(qint64 length) @@ -97,7 +97,7 @@ void FileInfo::setMetaData(Qmmp::MetaData key, int value) m_metaData.insert(key, QString::number(value)); } -void FileInfo::setUrl(const QUrl &url) +void FileInfo::setPath(const QString &path) { - m_url = url; + m_path = path; } diff --git a/src/qmmp/fileinfo.h b/src/qmmp/fileinfo.h index a2e70188e..c01ac4306 100644 --- a/src/qmmp/fileinfo.h +++ b/src/qmmp/fileinfo.h @@ -32,7 +32,7 @@ class FileInfo { public: - FileInfo(); + FileInfo(const QString &path = QString()); FileInfo(const FileInfo &other); ~FileInfo(); @@ -45,20 +45,18 @@ public: const QString metaData (Qmmp::MetaData key) const; const QMap<Qmmp::MetaData, QString> metaData () const; bool isEmpty() const; - const QUrl url() const; - int count(); + const QString path() const; void setLength(qint64 length); void setMetaData(Qmmp::MetaData key, const QString &value); void setMetaData(Qmmp::MetaData key, int value); void setMetaData(const QMap <Qmmp::MetaData, QString> &metaData); - void setUrl(const QUrl &url); + void setPath(const QString &path); private: QMap <Qmmp::MetaData, QString> m_metaData; qint64 m_length; - QUrl m_url; - int m_count; + QString m_path; QList<QMap<int, int> > map; }; diff --git a/src/qmmp/soundcore.cpp b/src/qmmp/soundcore.cpp index 7cb59cb05..7742ca92d 100644 --- a/src/qmmp/soundcore.cpp +++ b/src/qmmp/soundcore.cpp @@ -54,6 +54,8 @@ SoundCore::SoundCore(QObject *parent) for (int i = 1; i < 10; ++i) m_bands[i] = 0; m_handler = new StateHandler(this); + //StateHandler::instance() = 0; + //StateHandler::m_instance = m_handler; connect(m_handler, SIGNAL(elapsedChanged(qint64)), SIGNAL(elapsedChanged(qint64))); connect(m_handler, SIGNAL(bitrateChanged(int)), SIGNAL(bitrateChanged(int))); connect(m_handler, SIGNAL(frequencyChanged(int)), SIGNAL(frequencyChanged(int))); @@ -74,23 +76,25 @@ SoundCore::~SoundCore() bool SoundCore::play(const QString &source) { stop(); + m_source = source; if (m_handler->state() != Qmmp::Stopped) //clear error state m_handler->dispatch(Qmmp::Stopped); + QUrl url; if (QFile::exists(source)) //local file - m_url = QUrl::fromLocalFile(source); + url = QUrl::fromLocalFile(source); else - m_url = source; + url = source; - m_factory = Decoder::findByURL(m_url); + m_factory = Decoder::findByURL(url); if (m_factory) return decode(); - if (m_url.scheme() == "file") + if (url.scheme() == "file") { - if ((m_factory = Decoder::findByPath(m_url.path()))) + if ((m_factory = Decoder::findByPath(m_source))) { - m_input = new QFile(m_url.path()); + m_input = new QFile(m_source); if (!m_input->open(QIODevice::ReadOnly)) { qDebug("SoundCore: cannot open input"); @@ -98,9 +102,13 @@ bool SoundCore::play(const QString &source) m_handler->dispatch(Qmmp::NormalError); return FALSE; } - FileInfo *finfo = m_factory->createFileInfo(m_url.toLocalFile ()); - m_handler->dispatch(finfo->metaData()); - delete finfo; + QList <FileInfo *> list = m_factory->createPlayList(url.toLocalFile ()); + if (!list.isEmpty()) + { + m_handler->dispatch(list[0]->metaData()); + while (!list.isEmpty()) + delete list.takeFirst(); + } return decode(); } else @@ -111,7 +119,7 @@ bool SoundCore::play(const QString &source) return FALSE; } } - if (m_url.scheme() == "http") + if (url.scheme() == "http") { m_input = new StreamReader(source, this); connect(m_input, SIGNAL(bufferingProgress(int)), SIGNAL(bufferingProgress(int))); @@ -128,8 +136,8 @@ bool SoundCore::play(const QString &source) void SoundCore::stop() { m_factory = 0; - m_url.clear(); - if (m_decoder && m_decoder->isRunning()) + m_source.clear(); + if (m_decoder /*&& m_decoder->isRunning()*/) { m_decoder->mutex()->lock (); m_decoder->stop(); @@ -224,6 +232,12 @@ void SoundCore::seek(qint64 pos) m_decoder->mutex()->unlock(); } } + else if (m_decoder) + { + m_decoder->mutex()->lock (); + m_decoder->seek(pos); + m_decoder->mutex()->unlock(); + } } qint64 SoundCore::length() const @@ -363,7 +377,8 @@ bool SoundCore::decode() return FALSE; } } - m_decoder = m_factory->create(this, m_input, m_output, m_url.path()); + m_decoder = m_factory->create(this, m_input, m_output, m_source); + m_decoder->setStateHandler(m_handler); if (!m_decoder) { qWarning("SoundCore: unsupported fileformat"); @@ -379,7 +394,8 @@ bool SoundCore::decode() if (m_decoder->initialize()) { - m_output->start(); + if (m_output) + m_output->start(); m_decoder->start(); return TRUE; } diff --git a/src/qmmp/soundcore.h b/src/qmmp/soundcore.h index b24dd886e..a4d5819d7 100644 --- a/src/qmmp/soundcore.h +++ b/src/qmmp/soundcore.h @@ -82,13 +82,12 @@ public: QString metaData(Qmmp::MetaData key); - - /*! * Returns a pointer to the SoundCore instance. */ static SoundCore* instance(); + public slots: void setSoftwareVolume(bool); @@ -148,7 +147,8 @@ private slots: private: Decoder* m_decoder; DecoderFactory* m_factory; - QUrl m_url; + //QUrl m_url; + QString m_source; Output* m_output; QIODevice* m_input; uint m_error; @@ -160,7 +160,6 @@ private: int m_bands[10]; Visual *m_vis; QList <Visual*> m_visuals; - QString m_source; QWidget *m_parentWidget; static SoundCore* m_instance; StateHandler *m_handler; diff --git a/src/qmmp/statehandler.cpp b/src/qmmp/statehandler.cpp index eceed5f76..20489f941 100644 --- a/src/qmmp/statehandler.cpp +++ b/src/qmmp/statehandler.cpp @@ -28,7 +28,8 @@ StateHandler* StateHandler::m_instance = 0; StateHandler::StateHandler(QObject *parent) : QObject(parent) { - m_instance = this; + if (!m_instance) + m_instance = this; m_elapsed = -1; m_bitrate = 0; m_frequency = 0; @@ -41,7 +42,8 @@ StateHandler::StateHandler(QObject *parent) StateHandler::~StateHandler() { - m_instance = 0; + if (m_instance == this) + m_instance = 0; } @@ -127,7 +129,7 @@ void StateHandler::dispatch(const Qmmp::State &state) m_metaData.clear(); } emit stateChanged(state); - if(m_state == Qmmp::Playing && m_sendMeta) + if (m_state == Qmmp::Playing && m_sendMeta) { m_sendMeta = FALSE; emit metaDataChanged (); diff --git a/src/qmmp/statehandler.h b/src/qmmp/statehandler.h index 6be225b4e..702a24c1b 100644 --- a/src/qmmp/statehandler.h +++ b/src/qmmp/statehandler.h @@ -37,16 +37,16 @@ public: ~StateHandler(); - void dispatch(qint64 elapsed, - qint64 totalTime, - int bitrate, - int frequency, - int precision, - int channels); + virtual void dispatch(qint64 elapsed, + qint64 totalTime, + int bitrate, + int frequency, + int precision, + int channels); - void dispatch(const QMap<Qmmp::MetaData, QString> &metaData); + virtual void dispatch(const QMap<Qmmp::MetaData, QString> &metaData); - void dispatch(const Qmmp::State &state); + virtual void dispatch(const Qmmp::State &state); qint64 elapsed(); int bitrate(); @@ -80,7 +80,6 @@ private: Qmmp::State m_state; QMutex m_mutex; bool m_sendMeta; - }; #endif diff --git a/src/ui/fileloader.cpp b/src/ui/fileloader.cpp index 6cf71e3b2..ce5ccb56c 100644 --- a/src/ui/fileloader.cpp +++ b/src/ui/fileloader.cpp @@ -43,8 +43,13 @@ void FileLoader::addFiles(const QStringList &files) foreach(QString s, files) { - if (s.startsWith("http://") || Decoder::supports(s)) - emit newPlayListItem(new PlayListItem(s)); + /*if (s.startsWith("http://") || Decoder::supports(s)) + {*/ + //emit newPlayListItem(new PlayListItem(s)); + QList <FileInfo *> playList = Decoder::createPlayList(s); + foreach(FileInfo *info, playList) + emit newPlayListItem(new PlayListItem(info)); + //} if (m_finished) return; } } @@ -52,6 +57,7 @@ void FileLoader::addFiles(const QStringList &files) void FileLoader::addDirectory(const QString& s) { + QList <FileInfo *> playList; QDir dir(s); dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); dir.setSorting(QDir::Name); @@ -62,8 +68,13 @@ void FileLoader::addDirectory(const QString& s) QString suff = fileInfo.completeSuffix(); list << fileInfo; - if (Decoder::supports(fileInfo.absoluteFilePath ())) - emit newPlayListItem(new PlayListItem(fileInfo.absoluteFilePath ())); + /*if (Decoder::supports(fileInfo.absoluteFilePath ())) + {*/ + playList = Decoder::createPlayList(fileInfo.absoluteFilePath ()); + foreach(FileInfo *info, playList) + emit newPlayListItem(new PlayListItem(info)); + //emit newPlayListItem(new PlayListItem(fileInfo.absoluteFilePath ())); + //} if (m_finished) return; } dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); @@ -79,7 +90,6 @@ void FileLoader::addDirectory(const QString& s) } } - void FileLoader::run() { if (!m_files_to_load.isEmpty()) @@ -88,8 +98,6 @@ void FileLoader::run() addDirectory(m_directory); } - - void FileLoader::setFilesToLoad(const QStringList & l) { m_files_to_load = l; diff --git a/src/ui/fileloader.h b/src/ui/fileloader.h index a67ec3567..d2dcc0748 100644 --- a/src/ui/fileloader.h +++ b/src/ui/fileloader.h @@ -27,46 +27,46 @@ class PlayListItem; /*! - * This class represents fileloader object that + * This class represents fileloader object that * processes file list in separate thread and emits * \b newPlayListItem(PlayListItem*) signal for every newly * created media file. - @author Ilya Kotov <forkotov02@hotmail.ru> + @author Ilya Kotov <forkotov02@hotmail.ru> */ class FileLoader : public QThread { -Q_OBJECT + Q_OBJECT public: FileLoader(QObject *parent = 0); ~FileLoader(); - virtual void run(); - - /*! - * Call this method when you want to notify the thread about finishing - */ - void finish(); - - /*! - * Sets filelist to load( directory to load will be cleaned ) - */ - void setFilesToLoad(const QStringList&); - - /*! - * Sets directory to load( filelist to load will be cleaned ) - */ - void setDirectoryToLoad(const QString&); + virtual void run(); + + /*! + * Call this method when you want to notify the thread about finishing + */ + void finish(); + + /*! + * Sets filelist to load( directory to load will be cleaned ) + */ + void setFilesToLoad(const QStringList&); + + /*! + * Sets directory to load( filelist to load will be cleaned ) + */ + void setDirectoryToLoad(const QString&); signals: - void newPlayListItem(PlayListItem*); + void newPlayListItem(PlayListItem*); protected: - void addFiles(const QStringList &files); - void addDirectory(const QString& s); + void addFiles(const QStringList &files); + void addDirectory(const QString& s); private: QFileInfoList list; QStringList m_filters; - QStringList m_files_to_load; - QString m_directory; - bool m_finished; + QStringList m_files_to_load; + QString m_directory; + bool m_finished; }; #endif diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index d2e50a98c..1cd0a26d3 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -181,7 +181,7 @@ void MainWindow::play() return; m_equalizer->loadPreset(m_playListModel->currentItem()->fileName()); - m_playListModel->currentItem()->updateTags(); + //m_playListModel->currentItem()->updateTags(); m_playlist->listWidget()->updateList(); QString s = m_playListModel->currentItem()->path(); if (s.isEmpty()) diff --git a/src/ui/playlistitem.cpp b/src/ui/playlistitem.cpp index b5321c8ca..738f8fdae 100644 --- a/src/ui/playlistitem.cpp +++ b/src/ui/playlistitem.cpp @@ -29,13 +29,14 @@ PlayListItem::PlayListItem() : SongInfo(), m_flag(FREE) m_info = 0; } -PlayListItem::PlayListItem(const QString& path) : SongInfo(), m_flag(FREE) +//PlayListItem::PlayListItem(const QString& path) : SongInfo(), m_flag(FREE) +PlayListItem::PlayListItem(FileInfo *info) : SongInfo(), m_flag(FREE) { m_selected = FALSE; m_current = FALSE; - m_info = 0; - setValue(SongInfo::PATH, path); - setValue(SongInfo::STREAM, path.startsWith("http://")); //TODO do this inside SongInfo + m_info = info; + setValue(SongInfo::PATH, info->path()); //TODO path? + setValue(SongInfo::STREAM, path().startsWith("http://")); //TODO do this inside SongInfo QSettings settings ( QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat ); m_use_meta = settings.value ("PlayList/load_metadata", TRUE).toBool(); //format @@ -45,15 +46,15 @@ PlayListItem::PlayListItem(const QString& path) : SongInfo(), m_flag(FREE) m_convertTwenty = settings.value ("PlayList/convert_twenty", TRUE).toBool(); m_fullStreamPath = settings.value ("PlayList/full_stream_path", FALSE).toBool(); - if (m_use_meta && !path.startsWith("http://")) + if (m_use_meta && !path().startsWith("http://")) { - m_info = Decoder::createFileInfo(path); + //m_info = Decoder::createFileInfo(path); readMetadata(); } - else if (path.startsWith("http://") && m_fullStreamPath) - m_title = path; + else if (path().startsWith("http://") && m_fullStreamPath) + m_title = path(); else - m_title = path.split('/',QString::SkipEmptyParts).takeLast (); + m_title = path().split('/',QString::SkipEmptyParts).takeLast (); } PlayListItem::~PlayListItem() @@ -111,7 +112,8 @@ void PlayListItem::updateTags() delete m_info; m_info = 0; } - m_info = Decoder::createFileInfo(path()); + //m_info = Decoder::createFileInfo(path()); + m_info = Decoder::createPlayList(path()).at(0); readMetadata(); } diff --git a/src/ui/playlistitem.h b/src/ui/playlistitem.h index 818bc7eeb..29181dcce 100644 --- a/src/ui/playlistitem.h +++ b/src/ui/playlistitem.h @@ -39,7 +39,8 @@ public: */ enum FLAGS{FREE = 0,EDITING,SCHEDULED_FOR_DELETION}; PlayListItem(); - PlayListItem(const QString& path); + //PlayListItem(const QString& path); + PlayListItem(FileInfo *info); ~PlayListItem(); diff --git a/src/ui/playlistmodel.cpp b/src/ui/playlistmodel.cpp index 327b88598..1a92d0bc3 100644 --- a/src/ui/playlistmodel.cpp +++ b/src/ui/playlistmodel.cpp @@ -314,10 +314,10 @@ void PlayListModel::showDetails() str.append(tr("Album:") + " %4\n"); str.append(tr("Comment:") + " %5"); str = str.arg(item->path()) - .arg(item->title().isEmpty() ? item->text() : item->title()) - .arg(item->artist()) - .arg(item->album()) - .arg(item->comment()); + .arg(item->title().isEmpty() ? item->text() : item->title()) + .arg(item->artist()) + .arg(item->album()) + .arg(item->comment()); QMessageBox::information(0, m_items.at (i)->path(), str); return; } @@ -365,7 +365,8 @@ void PlayListModel::readSettings() for (int i = 0;i < preload;i++) { - load(new PlayListItem(files.takeAt(0))); + //TODO load tags from cache + load(new PlayListItem(Decoder::createPlayList(files.takeAt(0)).at(0))); } if (files.isEmpty()) @@ -398,10 +399,13 @@ void PlayListModel::addFile(const QString& path) { if (path.isEmpty ()) return; - if (path.startsWith("http://")) + /*if (path.startsWith("http://")) load(new PlayListItem(path)); else if (Decoder::supports(path)) - load(new PlayListItem(path)); + load(new PlayListItem(path));*/ + QList <FileInfo *> playList = Decoder::createPlayList(path); + foreach(FileInfo *info, playList) + emit load(new PlayListItem(info)); m_play_state->prepare(); } |
