aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/qmmp/CMakeLists.txt1
-rw-r--r--src/qmmp/abstractengine.cpp62
-rw-r--r--src/qmmp/abstractengine.h41
-rw-r--r--src/qmmp/enginefactory.h108
-rw-r--r--src/qmmp/qmmp.pro4
-rw-r--r--src/qmmp/qmmpaudioengine.cpp1
-rw-r--r--src/qmmp/soundcore.h7
7 files changed, 188 insertions, 36 deletions
diff --git a/src/qmmp/CMakeLists.txt b/src/qmmp/CMakeLists.txt
index a3db3d97a..3af5a05c3 100644
--- a/src/qmmp/CMakeLists.txt
+++ b/src/qmmp/CMakeLists.txt
@@ -80,6 +80,7 @@ SET(libqmmp_MOC_HDRS
inputsource.h
fileinputsource.h
emptyinputsource.h
+ enginefactory.h
)
SET(libqmmp_DEVEL_HDRS
diff --git a/src/qmmp/abstractengine.cpp b/src/qmmp/abstractengine.cpp
index b92c3e069..e8c7c309a 100644
--- a/src/qmmp/abstractengine.cpp
+++ b/src/qmmp/abstractengine.cpp
@@ -18,6 +18,12 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#include <QSettings>
+#include <QDir>
+#include <QPluginLoader>
+#include <QApplication>
+#include "enginefactory.h"
+#include "qmmp.h"
#include "abstractengine.h"
AbstractEngine::AbstractEngine(QObject *parent) : QThread(parent)
@@ -33,3 +39,59 @@ QWaitCondition *AbstractEngine::cond()
{
return &m_waitCondition;
}
+
+// static methods
+QList<EngineFactory*> *AbstractEngine::m_factories = 0;
+QStringList AbstractEngine::m_files;
+
+void AbstractEngine::checkFactories()
+{
+ QSettings settings (Qmmp::configFile(), QSettings::IniFormat);
+
+ if (!m_factories)
+ {
+ m_files.clear();
+ m_factories = new QList<EngineFactory *>;
+
+ QDir pluginsDir (Qmmp::pluginsPath());
+ pluginsDir.cd("Engines");
+ foreach (QString fileName, pluginsDir.entryList(QDir::Files))
+ {
+ QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
+ QObject *plugin = loader.instance();
+ if (loader.isLoaded())
+ qDebug("AbstractEngine: plugin loaded - %s", qPrintable(fileName));
+ else
+ qWarning("AbstractEngine: %s", qPrintable(loader.errorString ()));
+ EngineFactory *factory = 0;
+ if (plugin)
+ factory = qobject_cast<EngineFactory *>(plugin);
+
+ if (factory)
+ {
+ m_factories->append(factory);
+ m_files << pluginsDir.absoluteFilePath(fileName);
+ qApp->installTranslator(factory->createTranslator(qApp));
+ }
+ }
+ //remove physically deleted plugins from disabled list
+ QStringList names;
+ foreach (EngineFactory *factory, *m_factories)
+ {
+ names.append(factory->properties().shortName);
+ }
+ QStringList disabledList = settings.value("Engine/disabled_plugins").toStringList ();
+ foreach (QString name, disabledList)
+ {
+ if (!names.contains(name))
+ disabledList.removeAll(name);
+ }
+ settings.setValue("Engine/disabled_plugins",disabledList);
+ }
+}
+
+QList<EngineFactory*> *AbstractEngine::factories()
+{
+ checkFactories();
+ return m_factories;
+}
diff --git a/src/qmmp/abstractengine.h b/src/qmmp/abstractengine.h
index 442e02da7..2f4bc2004 100644
--- a/src/qmmp/abstractengine.h
+++ b/src/qmmp/abstractengine.h
@@ -21,18 +21,18 @@
#ifndef ABSTRACTENGINE_H
#define ABSTRACTENGINE_H
-
#include <QMutex>
#include <QWaitCondition>
#include <QThread>
+#include <QStringList>
class QIODevice;
class InputSource;
+class EngineFactory;
/*!
* @author Ilya Kotov <forkotov02@hotmail.ru>
*/
-
class AbstractEngine : public QThread
{
Q_OBJECT
@@ -43,7 +43,6 @@ public:
* Prepares decoder for usage.
* Subclass should reimplement this function.
*/
- //virtual bool initialize(const QString &source, QIODevice *input = 0) = 0;
virtual bool enqueue(InputSource *source) = 0;
/*!
* Returns the total time in milliseconds.
@@ -59,23 +58,9 @@ public:
*/
virtual void stop() = 0;
/*!
- * Returns current bitrate (in kbps).
- * Subclass should reimplement this function.
- */
- //virtual int bitrate();
- /*!
- * Requests playback to pause. If it was paused already, playback should resume.
- * Subclass with own output should reimplement this function.
- */
- //virtual void pause();
- /*!
- * Returns decoder input or 0 if input is not specified.
+ * Pauses/resumes playback
*/
- //QIODevice *input();
- /*!
- * Returns decoder output or 0 if output is not specified.
- */
- //Output *output();
+ virtual void pause() = 0;
/*!
* Returns mutex pointer.
*/
@@ -88,16 +73,16 @@ public:
* Sets equalizer settings. Each item of \p bands[] and \p reamp should be \b -20.0..20.0
* Subclass with own equalizer should reimplement this function.
*/
- //virtual void setEQ(double bands[10], double preamp);
+ virtual void setEQ(double bands[10], double preamp) = 0;
/*!
* Enables equalizer if \p on is \b true or disables it if \p on is \b false
* Subclass with own equalizer should reimplement this function.
*/
- //virtual void setEQEnabled(bool on);
+ virtual void setEQEnabled(bool on) = 0;
/*!
- * Returns \b true if \b file is supported by input plugins, otherwise returns \b false
+ * Returns a list of decoder factories.
*/
- //bool supports(const QString &file);
+ static QList<EngineFactory*> *factories();
signals:
/*!
@@ -111,15 +96,13 @@ protected:
*/
virtual void run() = 0;
-protected slots:
- /*!
- * Subclass should call this slot when decoding is finished.
- */
- //void finish();
-
private:
QMutex m_mutex;
QWaitCondition m_waitCondition;
+
+ static void checkFactories();
+ static QList<EngineFactory*> *m_factories;
+ static QStringList m_files;
};
diff --git a/src/qmmp/enginefactory.h b/src/qmmp/enginefactory.h
new file mode 100644
index 000000000..dc38ac46a
--- /dev/null
+++ b/src/qmmp/enginefactory.h
@@ -0,0 +1,108 @@
+/***************************************************************************
+ * Copyright (C) 2009 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 EMGINEFACTORY_H
+#define EMGINEFACTORY_H
+
+class QObject;
+class QString;
+class QIODevice;
+class QWidget;
+class QTranslator;
+class MetaDataModel;
+class FileInfo;
+class AbstractEngine;
+
+/*! @brief Helper class to store custom audio engine properies.
+ * @author Ilya Kotov <forkotov02@hotmail.ru>
+ */
+class EngineProperties
+{
+public:
+ /*!
+ * Constructor
+ */
+ EngineProperties()
+ {
+ hasAbout = FALSE;
+ hasSettings = FALSE;
+ }
+ QString name; /*!< Input plugin full name */
+ QString shortName; /*!< Input plugin short name for internal usage */
+ QString filter; /*!< File filter (example: "*.mp3 *.ogg") */
+ QString description; /*!< File filter description */
+ QString contentType; /*!< Supported content types */
+ QString protocols; /*!< Supported protocols. Should be empty if plugin uses stream input. */
+ bool hasAbout; /*!< Should be \b true if plugin has about dialog, otherwise returns \b false */
+ bool hasSettings; /*!< Should be \b true if plugin has settings dialog, otherwise returns \b false */
+};
+/*! @brief Engine plugin interface.
+ * @author Ilya Kotov <forkotov02@hotmail.ru>
+ */
+class EngineFactory
+{
+public:
+ /*!
+ * Object destructor.
+ */
+ virtual ~EngineFactory() {}
+ /*!
+ * Returns general plugin properties.
+ */
+ virtual const EngineProperties properties() const = 0;
+ /*!
+ * Creates engine object.
+ * @param parent Parent object File path
+ */
+ virtual AbstractEngine *create(QObject *parent = 0) = 0;
+ /*!
+ * Extracts metadata and audio information from file \b path and returns a list of FileInfo items.
+ * One file may contain several playlist items (for example: cda disk or flac with embedded cue)
+ * @param fileName File path.
+ * @param useMetaData Metadata usage (\b true - use, \b - do not use)
+ */
+ virtual QList<FileInfo *> createPlayList(const QString &fileName, bool useMetaData) = 0;
+ /*!
+ * Creats metadata object, which provides full access to file tags.
+ * @param path File path.
+ * @param parent Parent object.
+ * @return MetaDataModel pointer.
+ */
+ virtual MetaDataModel* createMetaDataModel(const QString &path, QObject *parent = 0) = 0;
+ /*!
+ * Shows settings dialog.
+ * @param parent Parent widget.
+ */
+ virtual void showSettings(QWidget *parent) = 0;
+ /*!
+ * Shows about dialog.
+ * @param parent Parent widget.
+ */
+ virtual void showAbout(QWidget *parent) = 0;
+ /*!
+ * Creates QTranslator object of the system locale. Should return 0 if translation doesn't exist.
+ * @param parent Parent object.
+ */
+ virtual QTranslator *createTranslator(QObject *parent) = 0;
+};
+
+Q_DECLARE_INTERFACE(EngineFactory, "EngineFactory/1.0");
+
+#endif
diff --git a/src/qmmp/qmmp.pro b/src/qmmp/qmmp.pro
index a921cba19..64283c851 100644
--- a/src/qmmp/qmmp.pro
+++ b/src/qmmp/qmmp.pro
@@ -26,7 +26,8 @@ HEADERS += recycler.h \
inputsource.h \
fileinputsource.h \
emptyinputsource.h \
- inputsourcefactory.h
+ inputsourcefactory.h \
+ enginefactory.h
SOURCES += recycler.cpp \
decoder.cpp \
output.cpp \
@@ -56,7 +57,6 @@ CONFIG += release \
warn_on \
qt \
thread
-
TEMPLATE = lib
VERSION = $$QMMP_VERSION
unix:isEmpty(LIB_DIR):LIB_DIR = /lib
diff --git a/src/qmmp/qmmpaudioengine.cpp b/src/qmmp/qmmpaudioengine.cpp
index 7630d480f..ac3f58e6b 100644
--- a/src/qmmp/qmmpaudioengine.cpp
+++ b/src/qmmp/qmmpaudioengine.cpp
@@ -449,6 +449,7 @@ void QmmpAudioEngine::flush(bool final)
m_output_at = 0;
break;
}
+
while ((!m_done && !m_finish) && m_output->recycler()->full())
{
mutex()->unlock();
diff --git a/src/qmmp/soundcore.h b/src/qmmp/soundcore.h
index d72d193ae..538a84f6e 100644
--- a/src/qmmp/soundcore.h
+++ b/src/qmmp/soundcore.h
@@ -29,7 +29,7 @@
class QIODevice;
class VolumeControl;
-class QmmpAudioEngine;
+class AbstractEngine;
class InputSource;
/*! \brief The SoundCore class provides a simple interface for audio playback.
@@ -105,9 +105,6 @@ public:
* Returns the metdata string associated with the given \b key.
*/
QString metaData(Qmmp::MetaData key);
-
- //bool enqueue(const QString &url);
-
/*!
* Returns a pointer to the SoundCore instance.
*/
@@ -222,7 +219,7 @@ private:
static SoundCore* m_instance;
StateHandler *m_handler;
VolumeControl *m_volumeControl;
- QmmpAudioEngine *m_engine;
+ AbstractEngine *m_engine;
QList<InputSource *> m_pendingSources;
};