Commit 12ec3fc5 authored by Sandro Andrade's avatar Sandro Andrade

Prepare architecture to use soundbackend plugins

parent 205b7387
...@@ -50,7 +50,7 @@ public: ...@@ -50,7 +50,7 @@ public:
virtual Minuet::IUiController *uiController() = 0; virtual Minuet::IUiController *uiController() = 0;
protected: protected:
ICore(QObject *parent = 0); explicit ICore(QObject *parent = 0);
static ICore *m_self; static ICore *m_self;
}; };
......
...@@ -35,8 +35,10 @@ class MINUETINTERFACES_EXPORT IPlugin : public QObject ...@@ -35,8 +35,10 @@ class MINUETINTERFACES_EXPORT IPlugin : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit IPlugin(QObject *parent = 0);
~IPlugin() override; ~IPlugin() override;
protected:
explicit IPlugin(QObject *parent = 0);
}; };
} }
......
...@@ -35,8 +35,10 @@ class MINUETINTERFACES_EXPORT IPluginController : public QObject ...@@ -35,8 +35,10 @@ class MINUETINTERFACES_EXPORT IPluginController : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit IPluginController(QObject *parent = 0);
~IPluginController() override; ~IPluginController() override;
protected:
explicit IPluginController(QObject *parent = 0);
}; };
} }
......
...@@ -26,7 +26,7 @@ namespace Minuet ...@@ -26,7 +26,7 @@ namespace Minuet
{ {
ISoundBackend::ISoundBackend(QObject *parent) ISoundBackend::ISoundBackend(QObject *parent)
: QObject(parent) : IPlugin(parent)
{ {
} }
......
...@@ -23,22 +23,49 @@ ...@@ -23,22 +23,49 @@
#ifndef MINUET_ISOUNDBACKEND_H #ifndef MINUET_ISOUNDBACKEND_H
#define MINUET_ISOUNDBACKEND_H #define MINUET_ISOUNDBACKEND_H
#include <QtCore/QObject> #include "iplugin.h"
#include <QJsonArray>
#include "minuetinterfacesexport.h" #include "minuetinterfacesexport.h"
namespace Minuet namespace Minuet
{ {
class MINUETINTERFACES_EXPORT ISoundBackend : public QObject class MINUETINTERFACES_EXPORT ISoundBackend : public IPlugin
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int pitch MEMBER m_pitch NOTIFY pitchChanged)
Q_PROPERTY(quint8 volume MEMBER m_volume NOTIFY volumeChanged)
Q_PROPERTY(quint8 tempo MEMBER m_tempo NOTIFY tempoChanged)
public: public:
explicit ISoundBackend(QObject *parent = 0);
~ISoundBackend() override; ~ISoundBackend() override;
public Q_SLOTS:
virtual void prepareFromExerciseOptions(QJsonArray selectedOptions, const QString &playMode) = 0;
virtual void prepareFromMidiFile(const QString &fileName) = 0;
virtual void play() = 0;
virtual void pause() = 0;
virtual void stop() = 0;
Q_SIGNALS:
void pitchChanged(int newPitch);
void volumeChanged(quint8 newVolume);
void tempoChanged(quint8 newTempo);
protected:
explicit ISoundBackend(QObject *parent = 0);
int m_pitch;
quint8 m_volume;
quint8 m_tempo;
}; };
} }
Q_DECLARE_INTERFACE(Minuet::ISoundBackend, "org.kde.minuet.ISoundBackend")
#endif #endif
...@@ -35,8 +35,10 @@ class MINUETINTERFACES_EXPORT IUiController : public QObject ...@@ -35,8 +35,10 @@ class MINUETINTERFACES_EXPORT IUiController : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit IUiController(QObject *parent = 0);
~IUiController() override; ~IUiController() override;
protected:
explicit IUiController(QObject *parent = 0);
}; };
} }
......
add_subdirectory(drumsticksoundbackend)
add_subdirectory(fluidsynthsoundbackend) add_subdirectory(fluidsynthsoundbackend)
set(drumsticksoundbackend_PLUGIN_SRCS
drumsticksoundbackend.cpp
)
add_library(minuetdrumsticksoundbackend MODULE ${drumsticksoundbackend_PLUGIN_SRCS})
target_link_libraries(minuetdrumsticksoundbackend
Qt5::Core
Minuet::Interfaces
)
install(TARGETS minuetdrumsticksoundbackend DESTINATION ${PLUGIN_INSTALL_DIR}/minuet/)
/****************************************************************************
**
** Copyright (C) 2016 by Sandro S. Andrade <sandroandrade@kde.org>
**
** 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) version 3 or any later version
** accepted by the membership of KDE e.V. (or its successor approved
** by the membership of KDE e.V.), which shall act as a proxy
** defined in Section 14 of version 3 of the license.
**
** 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, see <http://www.gnu.org/licenses/>.
**
****************************************************************************/
#include "drumsticksoundbackend.h"
DrumstickSoundBackend::DrumstickSoundBackend(QObject *parent)
: Minuet::ISoundBackend(parent)
{
}
DrumstickSoundBackend::~DrumstickSoundBackend()
{
}
void DrumstickSoundBackend::prepareFromExerciseOptions(QJsonArray selectedOptions, const QString &playMode)
{
Q_UNUSED(selectedOptions)
Q_UNUSED(playMode)
}
void DrumstickSoundBackend::prepareFromMidiFile(const QString &fileName)
{
Q_UNUSED(fileName)
}
void DrumstickSoundBackend::play()
{
}
void DrumstickSoundBackend::pause()
{
}
void DrumstickSoundBackend::stop()
{
}
#include "moc_drumsticksoundbackend.cpp"
/****************************************************************************
**
** Copyright (C) 2016 by Sandro S. Andrade <sandroandrade@kde.org>
**
** 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) version 3 or any later version
** accepted by the membership of KDE e.V. (or its successor approved
** by the membership of KDE e.V.), which shall act as a proxy
** defined in Section 14 of version 3 of the license.
**
** 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, see <http://www.gnu.org/licenses/>.
**
****************************************************************************/
#ifndef MINUET_DRUMSTICKSOUNDBACKEND_H
#define MINUET_DRUMSTICKSOUNDBACKEND_H
#include <interfaces/isoundbackend.h>
class DrumstickSoundBackend : public Minuet::ISoundBackend
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.minuet.IPlugin" FILE "drumsticksoundbackend.json")
Q_INTERFACES(Minuet::IPlugin)
Q_INTERFACES(Minuet::ISoundBackend)
public:
explicit DrumstickSoundBackend(QObject *parent = 0);
virtual ~DrumstickSoundBackend() override;
public Q_SLOTS:
virtual void prepareFromExerciseOptions(QJsonArray selectedOptions, const QString &playMode) override;
virtual void prepareFromMidiFile(const QString &fileName) override;
virtual void play() override;
virtual void pause() override;
virtual void stop() override;
};
#endif
{
"KPlugin": {
"Category": "Sound Backends",
"Description": "This plugin provides Minuet with a Drumstick-based implementation of sound backend.",
"Icon": "utilities-terminal",
"Id": "minuetdrumsticksoundbackend",
"Name": "Drumstick-based Audio Backend",
"ServiceTypes": [
"Minuet/Plugin"
]
}
}
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "fluidsynthsoundbackend.h" #include "fluidsynthsoundbackend.h"
FluidSynthSoundBackend::FluidSynthSoundBackend(QObject *parent) FluidSynthSoundBackend::FluidSynthSoundBackend(QObject *parent)
: Minuet::IPlugin(parent) : Minuet::ISoundBackend(parent)
{ {
} }
...@@ -31,5 +31,28 @@ FluidSynthSoundBackend::~FluidSynthSoundBackend() ...@@ -31,5 +31,28 @@ FluidSynthSoundBackend::~FluidSynthSoundBackend()
{ {
} }
void FluidSynthSoundBackend::prepareFromExerciseOptions(QJsonArray selectedOptions, const QString &playMode)
{
Q_UNUSED(selectedOptions)
Q_UNUSED(playMode)
}
void FluidSynthSoundBackend::prepareFromMidiFile(const QString &fileName)
{
Q_UNUSED(fileName)
}
void FluidSynthSoundBackend::play()
{
}
void FluidSynthSoundBackend::pause()
{
}
void FluidSynthSoundBackend::stop()
{
}
#include "moc_fluidsynthsoundbackend.cpp" #include "moc_fluidsynthsoundbackend.cpp"
...@@ -23,17 +23,27 @@ ...@@ -23,17 +23,27 @@
#ifndef MINUET_FLUIDSYNTHSOUNDBACKEND_H #ifndef MINUET_FLUIDSYNTHSOUNDBACKEND_H
#define MINUET_FLUIDSYNTHSOUNDBACKEND_H #define MINUET_FLUIDSYNTHSOUNDBACKEND_H
#include <interfaces/iplugin.h> #include <interfaces/isoundbackend.h>
class FluidSynthSoundBackend : public Minuet::IPlugin class FluidSynthSoundBackend : public Minuet::ISoundBackend
{ {
Q_OBJECT Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.minuet.IPlugin" FILE "fluidsynthsoundbackend.json") Q_PLUGIN_METADATA(IID "org.kde.minuet.IPlugin" FILE "fluidsynthsoundbackend.json")
Q_INTERFACES(Minuet::IPlugin) Q_INTERFACES(Minuet::IPlugin)
Q_INTERFACES(Minuet::ISoundBackend)
public: public:
explicit FluidSynthSoundBackend(QObject *parent = 0); explicit FluidSynthSoundBackend(QObject *parent = 0);
~FluidSynthSoundBackend() override; virtual ~FluidSynthSoundBackend() override;
public Q_SLOTS:
virtual void prepareFromExerciseOptions(QJsonArray selectedOptions, const QString &playMode) override;
virtual void prepareFromMidiFile(const QString &fileName) override;
virtual void play() override;
virtual void pause() override;
virtual void stop() override;
}; };
#endif #endif
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "exercisecontroller.h" #include "exercisecontroller.h"
#include "uicontroller.h" #include "uicontroller.h"
#include <interfaces/isoundbackend.h>
namespace Minuet namespace Minuet
{ {
...@@ -50,7 +52,7 @@ IPluginController *Core::pluginController() ...@@ -50,7 +52,7 @@ IPluginController *Core::pluginController()
ISoundBackend *Core::soundBackend() ISoundBackend *Core::soundBackend()
{ {
return 0; return m_soundBackend;
} }
IExerciseController *Core::exerciseController() IExerciseController *Core::exerciseController()
...@@ -63,14 +65,20 @@ IUiController *Core::uiController() ...@@ -63,14 +65,20 @@ IUiController *Core::uiController()
return m_uiController.data(); return m_uiController.data();
} }
void Core::setSoundBackend(ISoundBackend *soundBackend)
{
m_soundBackend = soundBackend;
}
Core::Core(QObject *parent) Core::Core(QObject *parent)
: ICore(parent), : ICore(parent),
m_pluginController(new PluginController), m_pluginController(new PluginController),
m_soundBackend(0),
m_exerciseController(new ExerciseController), m_exerciseController(new ExerciseController),
m_uiController(new UiController) m_uiController(new UiController)
{ {
((PluginController *)m_pluginController.data())->initialize(); ((PluginController *)m_pluginController.data())->initialize(this);
((UiController *)m_uiController.data())->initialize(); ((UiController *)m_uiController.data())->initialize();
} }
......
...@@ -44,10 +44,13 @@ public: ...@@ -44,10 +44,13 @@ public:
virtual IExerciseController *exerciseController() override; virtual IExerciseController *exerciseController() override;
virtual IUiController *uiController() override; virtual IUiController *uiController() override;
void setSoundBackend(ISoundBackend *soundBackend);
private: private:
Core(QObject *parent = 0); Core(QObject *parent = 0);
QScopedPointer<IPluginController> m_pluginController; QScopedPointer<IPluginController> m_pluginController;
ISoundBackend *m_soundBackend;
QScopedPointer<IExerciseController> m_exerciseController; QScopedPointer<IExerciseController> m_exerciseController;
QScopedPointer<IUiController> m_uiController; QScopedPointer<IUiController> m_uiController;
}; };
......
...@@ -191,21 +191,21 @@ void MidiSequencer::generateSong(QJsonArray selectedOptions) ...@@ -191,21 +191,21 @@ void MidiSequencer::generateSong(QJsonArray selectedOptions)
for (int i = 0; i < selectedOptions.size(); ++i) { for (int i = 0; i < selectedOptions.size(); ++i) {
QString sequence = selectedOptions[i].toObject()[QStringLiteral("sequence")].toString(); QString sequence = selectedOptions[i].toObject()[QStringLiteral("sequence")].toString();
unsigned int m_chosenRootNote = selectedOptions[i].toObject()[QStringLiteral("rootNote")].toString().toInt(); unsigned int chosenRootNote = selectedOptions[i].toObject()[QStringLiteral("rootNote")].toString().toInt();
if (m_playMode != RhythmPlayMode) { if (m_playMode != RhythmPlayMode) {
appendEvent(SMFNoteOn(1, m_chosenRootNote, 120), barStart); appendEvent(SMFNoteOn(1, chosenRootNote, 120), barStart);
appendEvent(SMFNoteOff(1, m_chosenRootNote, 120), barStart + 60); appendEvent(SMFNoteOff(1, chosenRootNote, 120), barStart + 60);
unsigned int j = 1; unsigned int j = 1;
drumstick::SequencerEvent *ev; drumstick::SequencerEvent *ev;
foreach(const QString &additionalNote, sequence.split(' ')) { foreach(const QString &additionalNote, sequence.split(' ')) {
appendEvent(ev = SMFNoteOn(1, appendEvent(ev = SMFNoteOn(1,
m_chosenRootNote + additionalNote.toInt(), chosenRootNote + additionalNote.toInt(),
120), 120),
(m_playMode == ScalePlayMode) ? barStart+60*j:barStart); (m_playMode == ScalePlayMode) ? barStart+60*j:barStart);
ev->setTag(0); ev->setTag(0);
appendEvent(ev = SMFNoteOff(1, appendEvent(ev = SMFNoteOff(1,
m_chosenRootNote + additionalNote.toInt(), chosenRootNote + additionalNote.toInt(),
120), 120),
(m_playMode == ScalePlayMode) ? barStart+60*(j+1):barStart+60); (m_playMode == ScalePlayMode) ? barStart+60*(j+1):barStart+60);
ev->setTag(0); ev->setTag(0);
......
...@@ -123,7 +123,6 @@ public Q_SLOTS: ...@@ -123,7 +123,6 @@ public Q_SLOTS:
void SMFError(const QString &errorStr); void SMFError(const QString &errorStr);
private Q_SLOTS: private Q_SLOTS:
// Slots for events generated when playing a MIDI // Slots for events generated when playing a MIDI
void eventReceived(drumstick::SequencerEvent *ev); void eventReceived(drumstick::SequencerEvent *ev);
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
#include <KPluginLoader> #include <KPluginLoader>
#include <interfaces/iplugin.h> #include <interfaces/iplugin.h>
#include <interfaces/isoundbackend.h>
#include "core.h"
#include <QDebug> #include <QDebug>
...@@ -48,7 +51,7 @@ PluginController::~PluginController() ...@@ -48,7 +51,7 @@ PluginController::~PluginController()
{ {
} }
bool PluginController::initialize() bool PluginController::initialize(Core *core)
{ {
foreach (const KPluginMetaData &pluginMetaData, m_plugins) foreach (const KPluginMetaData &pluginMetaData, m_plugins)
{ {
...@@ -57,8 +60,14 @@ bool PluginController::initialize() ...@@ -57,8 +60,14 @@ bool PluginController::initialize()
KPluginLoader loader(pluginMetaData.fileName()); KPluginLoader loader(pluginMetaData.fileName());
IPlugin *plugin = qobject_cast<IPlugin *>(loader.instance()); IPlugin *plugin = qobject_cast<IPlugin *>(loader.instance());
if (plugin) if (plugin) {
m_loadedPlugins.insert(pluginMetaData, plugin); m_loadedPlugins.insert(pluginMetaData, plugin);
ISoundBackend *soundBackend = 0;
if (!core->soundBackend() && (soundBackend = qobject_cast<ISoundBackend *>(plugin))) {
qDebug() << "Setting soundbackend to" << soundBackend->metaObject()->className();
core->setSoundBackend(soundBackend);
}
}
} }
return true; return true;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
namespace Minuet namespace Minuet
{ {
class Core;
class IPlugin; class IPlugin;
class MINUETSHELL_EXPORT PluginController : public IPluginController class MINUETSHELL_EXPORT PluginController : public IPluginController
...@@ -42,7 +43,7 @@ public: ...@@ -42,7 +43,7 @@ public:
PluginController(QObject *parent = 0); PluginController(QObject *parent = 0);
~PluginController() override; ~PluginController() override;
bool initialize(); bool initialize(Core *core);
private: private:
QVector<KPluginMetaData> m_plugins; QVector<KPluginMetaData> m_plugins;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment