diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | core/qmpmidiplay.cpp | 6 | ||||
-rw-r--r-- | core/qmpmidiplay.hpp | 14 | ||||
-rw-r--r-- | include/qmpcorepublic.hpp | 57 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmidiplayer-desktop.pro | 9 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpchannelswindow.hpp | 4 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmphelpwindow.hpp | 2 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpmainwindow.cpp | 4 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpmainwindow.hpp | 3 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpplugin.cpp | 58 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpplugin.hpp | 26 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpsettingswindow.hpp | 2 | ||||
-rw-r--r-- | qmidiplayer-lite/qmidiplayer-lite.pro | 3 |
13 files changed, 169 insertions, 22 deletions
@@ -1,3 +1,6 @@ +2016-04-23 0.7.8 alpha +Basic stubs for plugin support. + 2016-04-22 0.7.2 Remove visualization stub in settings window. Warn the user when an invalid file is loaded. diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp index e33f804..cbed018 100644 --- a/core/qmpmidiplay.cpp +++ b/core/qmpmidiplay.cpp @@ -49,6 +49,7 @@ void CMidiPlayer::fluidDeinitialize() } void CMidiPlayer::processEvent(const SEvent *e) { + SEventCallBackData cbd(e->type,e->p1,e->p2); switch(e->type&0xF0) { case 0x80://Note off @@ -60,7 +61,7 @@ void CMidiPlayer::processEvent(const SEvent *e) case 0x90://Note on if((mute>>(e->type&0x0F))&1)break;//muted if(solo&&!((solo>>(e->type&0x0F))&1))break; - if(noteOnCB)noteOnCB->callBack(noteOnCBUserData); + if(noteOnCB)noteOnCB->callBack(&cbd,noteOnCBUserData); if(mappedoutput[e->type&0x0F]) mapper->noteOn(mappedoutput[e->type&0x0F]-1,e->type&0x0F,e->p1,e->p2); else @@ -397,6 +398,7 @@ uint32_t CMidiPlayer::getFileStandard(){return midiFile?midiFile->getStandard(): const char* CMidiPlayer::getTitle(){return midiFile?midiFile->getTitle():"";} const char* CMidiPlayer::getCopyright(){return midiFile?midiFile->getCopyright():"";} double CMidiPlayer::getTempo(){return 60./(ctempo/1e6);} +uint32_t CMidiPlayer::getDivision(){return divs;} uint32_t CMidiPlayer::getTCpaused(){return tcpaused;} void CMidiPlayer::setTCpaused(uint32_t ps){tcpaused=ps;} uint32_t CMidiPlayer::isFinished(){return finished;} @@ -528,5 +530,5 @@ void CMidiPlayer::setChannelOutput(int ch,int devid) }else fluid_synth_all_notes_off(synth,ch); } uint8_t* CMidiPlayer::getChstates(){return chstate;} -void CMidiPlayer::setNoteOnCallBack(CMidiCallBack *cb,void *userdata) +void CMidiPlayer::setNoteOnCallBack(IMidiCallBack *cb,void *userdata) {noteOnCB=cb;noteOnCBUserData=userdata;} diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp index 9bb6323..4f3b50f 100644 --- a/core/qmpmidiplay.hpp +++ b/core/qmpmidiplay.hpp @@ -2,10 +2,10 @@ #ifndef QMPMIDIPLAY_H #define QMPMIDIPLAY_H #include <cstring> -#include <cstdint> #include <cstdlib> #include <vector> #include <fluidsynth.h> +#include "../include/qmpcorepublic.hpp" #include "qmpmidimappers.hpp" struct SEvent { @@ -21,13 +21,6 @@ struct SEvent if(s){str=new char[strlen(s)+2];strcpy(str,s);}else str=NULL; } }; -class CMidiCallBack -{ - public: - CMidiCallBack(){} - virtual void callBack(void* data)=0; - virtual ~CMidiCallBack(){} -}; class CMidiFile { private: @@ -83,7 +76,7 @@ class CMidiPlayer qmpMidiMapperRtMidi *mapper; int mappedoutput[16],deviceusage[16],deviceiid[128]; uint8_t chstate[16],chstatus[16][130];//0..127: cc 128: pc - CMidiCallBack *noteOnCB; + IMidiCallBack *noteOnCB; void* noteOnCBUserData; void setBit(uint16_t &n,uint16_t bn,uint16_t b); @@ -126,6 +119,7 @@ class CMidiPlayer uint32_t getFileNoteCount(); uint32_t getFileStandard(); double getTempo(); + uint32_t getDivision(); const char* getTitle(); const char* getCopyright(); @@ -154,6 +148,6 @@ class CMidiPlayer qmpMidiMapperRtMidi* getMidiMapper(); void setChannelOutput(int ch,int devid); uint8_t* getChstates(); - void setNoteOnCallBack(CMidiCallBack *cb,void *userdata); + void setNoteOnCallBack(IMidiCallBack *cb,void *userdata); }; #endif diff --git a/include/qmpcorepublic.hpp b/include/qmpcorepublic.hpp new file mode 100644 index 0000000..7348beb --- /dev/null +++ b/include/qmpcorepublic.hpp @@ -0,0 +1,57 @@ +#ifndef QMPCOREPUBLIC_H +#define QMPCOREPUBLIC_H +#include <cstdint> +#include <string> +struct SEventCallBackData +{ + uint32_t type,p1,p2; + SEventCallBackData(uint32_t _t,uint32_t _p1,uint32_t _p2){type=_t;p1=_p1;p2=_p2;} +}; +class IMidiCallBack +{ + public: + IMidiCallBack(){} + virtual void callBack(void* callerdata,void* userdata)=0; + virtual ~IMidiCallBack(){} +}; +class qmpPluginIntf +{ + public: + virtual void init(); + virtual void deinit(); + virtual const char* pluginGetName(); + virtual const char* pluginGetVersion(); +}; +class qmpVisualizationIntf +{ + public: + virtual void show(); + virtual void close(); +}; +class qmpPluginAPI +{ + public: + uint32_t getDivision(); + uint32_t getRawTempo(); + double getRealTempo(); + uint32_t getTimeSig(); + uint32_t getKeySig(); + uint32_t getNoteCount(); + uint32_t getCurrentPolyphone(); + uint32_t getMaxPolyphone(); + uint32_t getCurrentTimeStamp(); + int registerVisualizationIntf(qmpVisualizationIntf* i); + void unregisterVisualizationIntf(int intfhandle); + int registerEventReadHandlerIntf(IMidiCallBack* cb,void* userdata); + void unregisterEventReadHandlerIntf(IMidiCallBack* cb,void* userdata); + int registerEventHandlerIntf(IMidiCallBack* cb,void* userdata); + void unregisterEventHandlerIntf(int intfhandle); + void registerOptionInt(std::string desc,std::string key,int defaultval); + int getOptionInt(std::string key); + void registerOptionDouble(std::string desc,std::string key,double defaultval); + double getOptionDouble(std::string key); + void registerOptionString(std::string desc,std::string key,std::string defaultval); + std::string getOptionString(std::string key); +}; +typedef qmpPluginIntf*(*qmpPluginEntry)(qmpPluginAPI*); +#endif // QMPCOREPUBLIC_H diff --git a/qmidiplayer-desktop/qmidiplayer-desktop.pro b/qmidiplayer-desktop/qmidiplayer-desktop.pro index 4eaf3dd..9e169e6 100644 --- a/qmidiplayer-desktop/qmidiplayer-desktop.pro +++ b/qmidiplayer-desktop/qmidiplayer-desktop.pro @@ -26,7 +26,8 @@ SOURCES += main.cpp\ qmpsettingswindow.cpp \ qmphelpwindow.cpp \ qdialskulpturestyle.cpp \ - ../core/qmpmidimapperrtmidi.cpp + ../core/qmpmidimapperrtmidi.cpp \ + qmpplugin.cpp HEADERS += qmpmainwindow.hpp \ ../core/qmpmidiplay.hpp \ @@ -39,7 +40,9 @@ HEADERS += qmpmainwindow.hpp \ qmpsettingswindow.hpp \ qmphelpwindow.hpp \ qdialskulpturestyle.hpp \ - ../core/qmpmidimappers.hpp + ../core/qmpmidimappers.hpp \ + ../include/qmpcorepublic.hpp \ + qmpplugin.hpp FORMS += qmpmainwindow.ui \ qmpplistwindow.ui \ @@ -78,7 +81,7 @@ unix{ menu.path = $${DATADIR}/menu menu.files += ./menu/$${TARGET} QMAKE_CXXFLAGS += -Wall - LIBS += -lfluidsynth -lrtmidi + LIBS += -lfluidsynth -lrtmidi -ldl } win32{ #change these before building... diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp index fef6ab7..15a53d6 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.hpp +++ b/qmidiplayer-desktop/qmpchannelswindow.hpp @@ -59,11 +59,11 @@ class QDCComboBox:public QComboBox void indexChangedSlot(int idx){emit(onChange(id,idx));} }; -class qmpCWNoteOnCB:public QObject,public CMidiCallBack +class qmpCWNoteOnCB:public QObject,public IMidiCallBack { Q_OBJECT public: - void callBack(void *data){if(data)data=NULL;emit(onNoteOn());} + void callBack(void*,void*){emit onNoteOn();} signals: void onNoteOn(); }; diff --git a/qmidiplayer-desktop/qmphelpwindow.hpp b/qmidiplayer-desktop/qmphelpwindow.hpp index 8264fcd..209a753 100644 --- a/qmidiplayer-desktop/qmphelpwindow.hpp +++ b/qmidiplayer-desktop/qmphelpwindow.hpp @@ -2,7 +2,7 @@ #define QMPHELPWINDOW_H #include <QDialog> -#define APP_VERSION "0.7.2" +#define APP_VERSION "0.7.8" namespace Ui { class qmpHelpWindow; diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp index 73c2895..84697a4 100644 --- a/qmidiplayer-desktop/qmpmainwindow.cpp +++ b/qmidiplayer-desktop/qmpmainwindow.cpp @@ -49,7 +49,7 @@ qmpMainWindow::qmpMainWindow(QWidget *parent) : ui->lnPolyphone->display("00000-00000"); ui->lbFileName->setText("");ref=this; playing=false;stopped=true;dragging=false; - settingsw=new qmpSettingsWindow(this); + settingsw=new qmpSettingsWindow(this);pmgr=new qmpPluginManager(); plistw=new qmpPlistWindow(this);player=NULL;timer=NULL; singleFS=qmpSettingsWindow::getSettingsIntf()->value("Behavior/SingleInstance",0).toInt(); } @@ -58,7 +58,7 @@ qmpMainWindow::~qmpMainWindow() { if(player)delete player; if(timer)delete timer; - delete ui; + delete pmgr;delete ui; } void qmpMainWindow::init() diff --git a/qmidiplayer-desktop/qmpmainwindow.hpp b/qmidiplayer-desktop/qmpmainwindow.hpp index 2f3876d..b88169b 100644 --- a/qmidiplayer-desktop/qmpmainwindow.hpp +++ b/qmidiplayer-desktop/qmpmainwindow.hpp @@ -15,6 +15,7 @@ #include <thread> #include <chrono> #include "../core/qmpmidiplay.hpp" +#include "qmpplugin.hpp" #include "qmpplistwindow.hpp" #include "qmpchannelswindow.hpp" #include "qmpefxwindow.hpp" @@ -57,6 +58,7 @@ class qmpMainWindow:public QMainWindow void dragEnterEvent(QDragEnterEvent *event); ~qmpMainWindow(); CMidiPlayer* getPlayer(){return player;} + qmpSettingsWindow* getSettingsWindow(){return settingsw;} QTimer* getTimer(){return timer;} bool isFinalizing(){return fin;} QString getFileName(); @@ -95,6 +97,7 @@ class qmpMainWindow:public QMainWindow std::chrono::steady_clock::time_point st; double offset; CMidiPlayer *player; + qmpPluginManager *pmgr; qmpPlistWindow *plistw; qmpChannelsWindow *chnlw; qmpEfxWindow *efxw; diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp new file mode 100644 index 0000000..4da1698 --- /dev/null +++ b/qmidiplayer-desktop/qmpplugin.cpp @@ -0,0 +1,58 @@ +#ifdef _WIN32 +#include <windows.h> +#else +#include <dlfcn.h> +#include <dirent.h> +#endif +#include <cstring> +#include "qmpplugin.hpp" +#include "qmpmainwindow.hpp" +#include "qmpsettingswindow.hpp" +qmpPluginAPI pluginAPI; +qmpMainWindow* qmw; +qmpSettingsWindow* qsw; +#ifdef _WIN32 +#else +void qmpPluginManager::scanPlugins() +{ + DIR *dir; + struct dirent *file; + std::vector<std::string> cpluginpaths; + if((dir=opendir("/usr/lib/qmidiplayer/"))) + { + while((file=readdir(dir))) + if(strcmp(file->d_name+strlen(file->d_name)-3,".so")==0) + cpluginpaths.push_back(std::string("/usr/lib/qmidiplayer/")+std::string(file->d_name)); + closedir(dir); + } + if((dir=opendir("./"))) + { + while((file=readdir(dir))) + if(strcmp(file->d_name+strlen(file->d_name)-3,".so")==0) + cpluginpaths.push_back(std::string("./")+std::string(file->d_name)); + closedir(dir); + } + for(unsigned i=0;i<cpluginpaths.size();++i) + { + void* hso=dlopen(cpluginpaths[i].c_str(),RTLD_LAZY); + if(!hso){fprintf(stderr,"%s\n",dlerror());continue;} + void* hndi=dlsym(hso,"qmpPluginGetInterface"); + if(!hndi)continue; + qmpPluginEntry e=(qmpPluginEntry)hndi; + qmpPluginIntf* intf=e(&pluginAPI); + plugins.push_back(qmpPlugin(std::string(intf->pluginGetName()),std::string(intf->pluginGetVersion()),std::string(cpluginpaths[i]),intf)); + } +} +#endif +qmpPluginManager::qmpPluginManager() +{ + qmw=qmpMainWindow::getInstance(); + qsw=qmw->getSettingsWindow(); +} +qmpPluginManager::~qmpPluginManager() +{ + qmw=NULL;qsw=NULL; +} + +uint32_t qmpPluginAPI::getDivision() +{return qmw->getPlayer()->getDivision();} diff --git a/qmidiplayer-desktop/qmpplugin.hpp b/qmidiplayer-desktop/qmpplugin.hpp new file mode 100644 index 0000000..8d14596 --- /dev/null +++ b/qmidiplayer-desktop/qmpplugin.hpp @@ -0,0 +1,26 @@ +#ifndef QMPPLUGIN_H +#define QMPPLUGIN_H +#include <string> +#include <vector> +#include "../include/qmpcorepublic.hpp" +struct qmpPlugin +{ + std::string name,version,path; + qmpPluginIntf* interface; + bool enabled; + qmpPlugin(std::string _n,std::string _v,std::string _p,qmpPluginIntf* _i) + {name=_n;version=_v;path=_p;interface=_i;enabled=false;} +}; +class qmpPluginManager +{ + private: + std::vector<qmpPlugin> plugins; + public: + qmpPluginManager(); + ~qmpPluginManager(); + std::vector<qmpPlugin> getPlugins() const; + void scanPlugins(); + void initPlugins(); + void deinitPlugins(); +}; +#endif // QMPPLUGIN_H diff --git a/qmidiplayer-desktop/qmpsettingswindow.hpp b/qmidiplayer-desktop/qmpsettingswindow.hpp index cac691e..6c95663 100644 --- a/qmidiplayer-desktop/qmpsettingswindow.hpp +++ b/qmidiplayer-desktop/qmpsettingswindow.hpp @@ -38,7 +38,7 @@ class qmpSettingsWindow:public QDialog void on_cbAutoBS_stateChanged(); - private: + private: Ui::qmpSettingsWindow *ui; void settingsUpdate(); static QSettings *settings; diff --git a/qmidiplayer-lite/qmidiplayer-lite.pro b/qmidiplayer-lite/qmidiplayer-lite.pro index 4dc53bc..7ee4771 100644 --- a/qmidiplayer-lite/qmidiplayer-lite.pro +++ b/qmidiplayer-lite/qmidiplayer-lite.pro @@ -21,7 +21,8 @@ include(deployment.pri) HEADERS += \ ../core/qmpmidiplay.hpp \ qmpcorewrapper.hpp \ - ../core/qmpmidimappers.hpp + ../core/qmpmidimappers.hpp \ + ../include/qmpcorepublic.hpp unix{ LIBS += -lfluidsynth -lrtmidi } |