diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | core/qmpmidiplay.cpp | 45 | ||||
-rw-r--r-- | core/qmpmidiplay.hpp | 17 | ||||
-rw-r--r-- | include/qmpcorepublic.hpp | 17 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpchannelswindow.cpp | 2 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpchannelswindow.hpp | 3 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpinfowindow.cpp | 2 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpmainwindow.cpp | 1 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpplugin.cpp | 33 | ||||
-rw-r--r-- | visualization/qmpvisualization.cpp | 45 | ||||
-rw-r--r-- | visualization/qmpvisualization.hpp | 36 | ||||
-rw-r--r-- | visualization/visualization.pro | 23 |
12 files changed, 213 insertions, 19 deletions
@@ -1,4 +1,12 @@ 2016-04-23 0.7.8 alpha +More implementation of plugin support. +Migrate channel activity indicator to the new +callback system. +Added a testing plugin. +Plugins are now loaded correctly. +However the plugin API is not working properly. + +2016-04-23 0.7.8 alpha Basic stubs for plugin support. 2016-04-22 0.7.2 diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp index cbed018..4e28be0 100644 --- a/core/qmpmidiplay.cpp +++ b/core/qmpmidiplay.cpp @@ -50,6 +50,8 @@ void CMidiPlayer::fluidDeinitialize() void CMidiPlayer::processEvent(const SEvent *e) { SEventCallBackData cbd(e->type,e->p1,e->p2); + for(int i=0;i<16;++i)if(eventHandlerCB[i]) + eventHandlerCB[i]->callBack(&cbd,eventHandlerCBuserdata[i]); switch(e->type&0xF0) { case 0x80://Note off @@ -61,7 +63,6 @@ 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(&cbd,noteOnCBUserData); if(mappedoutput[e->type&0x0F]) mapper->noteOn(mappedoutput[e->type&0x0F]-1,e->type&0x0F,e->p1,e->p2); else @@ -272,7 +273,10 @@ CMidiPlayer::CMidiPlayer(bool singleInst) { midiFile=NULL;resumed=false;singleInstance=singleInst; settings=NULL;synth=NULL;adriver=NULL;waitvoice=true; - noteOnCB=NULL;noteOnCBUserData=NULL; + memset(eventHandlerCB,0,sizeof(eventHandlerCB)); + memset(eventHandlerCBuserdata,0,sizeof(eventHandlerCBuserdata)); + memset(eventReaderCB,0,sizeof(eventReaderCB)); + memset(eventReaderCBuserdata,0,sizeof(eventReaderCBuserdata)); memset(mappedoutput,0,sizeof(mappedoutput)); memset(deviceusage,0,sizeof(deviceusage)); mapper=new qmpMidiMapperRtMidi(); @@ -314,6 +318,8 @@ void CMidiPlayer::playerPanic(bool reset) bool CMidiPlayer::playerLoadFile(const char* fn) { midiFile=new CMidiFile(fn); + memcpy(midiFile->eventReaderCB,this->eventReaderCB,sizeof(this->eventReaderCB)); + memcpy(midiFile->eventReaderCBuserdata,this->eventReaderCBuserdata,sizeof(this->eventReaderCBuserdata)); if(!midiFile->isValid())return false; divs=midiFile->getDivision(); fileTimer1Pass(); @@ -392,12 +398,13 @@ void CMidiPlayer::setTCeptr(uint32_t ep,uint32_t st) } double CMidiPlayer::getFtime(){return ftime;} void CMidiPlayer::getCurrentTimeSignature(int *n,int *d){*n=ctsn;*d=ctsd;} -void CMidiPlayer::getCurrentKeySignature(int *ks){*ks=cks;} +int CMidiPlayer::getCurrentKeySignature(){return cks;} uint32_t CMidiPlayer::getFileNoteCount(){return midiFile?midiFile->getNoteCount():0;} uint32_t CMidiPlayer::getFileStandard(){return midiFile?midiFile->getStandard():0;} 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::getRawTempo(){return ctempo;} uint32_t CMidiPlayer::getDivision(){return divs;} uint32_t CMidiPlayer::getTCpaused(){return tcpaused;} void CMidiPlayer::setTCpaused(uint32_t ps){tcpaused=ps;} @@ -530,5 +537,33 @@ void CMidiPlayer::setChannelOutput(int ch,int devid) }else fluid_synth_all_notes_off(synth,ch); } uint8_t* CMidiPlayer::getChstates(){return chstate;} -void CMidiPlayer::setNoteOnCallBack(IMidiCallBack *cb,void *userdata) -{noteOnCB=cb;noteOnCBUserData=userdata;} +int CMidiPlayer::setEventHandlerCB(IMidiCallBack *cb,void *userdata) +{ + for(int i=0;i<16;++i) + { + if(eventHandlerCB[i]==cb)return i; + if(eventHandlerCB[i]==NULL) + { + eventHandlerCB[i]=cb;eventHandlerCBuserdata[i]=userdata; + return i; + } + } + return -1; +} +void CMidiPlayer::unsetEventHandlerCB(int id) +{eventHandlerCB[id]=NULL;eventHandlerCBuserdata[id]=NULL;} +int CMidiPlayer::setEventReaderCB(IMidiCallBack *cb,void *userdata) +{ + for(int i=0;i<16;++i) + { + if(eventReaderCB[i]==cb)return i; + if(eventReaderCB[i]==NULL) + { + eventReaderCB[i]=cb;eventReaderCBuserdata[i]=userdata; + return i; + } + } + return -1; +} +void CMidiPlayer::unsetEventReaderCB(int id) +{eventReaderCB[id]=NULL;eventReaderCBuserdata[id]=NULL;} diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp index 4f3b50f..35fecea 100644 --- a/core/qmpmidiplay.hpp +++ b/core/qmpmidiplay.hpp @@ -23,6 +23,7 @@ struct SEvent }; class CMidiFile { + friend class CMidiPlayer; private: std::vector<SEvent*>eventList; char *title,*copyright; @@ -31,6 +32,8 @@ class CMidiFile FILE *f; int byteread,valid; uint32_t notes,curt,curid; + IMidiCallBack* eventReaderCB[16]; + void* eventReaderCBuserdata[16]; void error(int fatal,const char* format,...); uint32_t readSW(); @@ -76,8 +79,10 @@ class CMidiPlayer qmpMidiMapperRtMidi *mapper; int mappedoutput[16],deviceusage[16],deviceiid[128]; uint8_t chstate[16],chstatus[16][130];//0..127: cc 128: pc - IMidiCallBack *noteOnCB; - void* noteOnCBUserData; + IMidiCallBack* eventHandlerCB[16]; + IMidiCallBack* eventReaderCB[16]; + void* eventHandlerCBuserdata[16]; + void* eventReaderCBuserdata[16]; void setBit(uint16_t &n,uint16_t bn,uint16_t b); void processEvent(const SEvent *e); @@ -115,10 +120,11 @@ class CMidiPlayer double getFtime(); void getCurrentTimeSignature(int *n,int *d); - void getCurrentKeySignature(int *ks); + int getCurrentKeySignature(); uint32_t getFileNoteCount(); uint32_t getFileStandard(); double getTempo(); + uint32_t getRawTempo(); uint32_t getDivision(); const char* getTitle(); const char* getCopyright(); @@ -148,6 +154,9 @@ class CMidiPlayer qmpMidiMapperRtMidi* getMidiMapper(); void setChannelOutput(int ch,int devid); uint8_t* getChstates(); - void setNoteOnCallBack(IMidiCallBack *cb,void *userdata); + int setEventHandlerCB(IMidiCallBack *cb,void *userdata); + void unsetEventHandlerCB(int id); + int setEventReaderCB(IMidiCallBack *cb,void *userdata); + void unsetEventReaderCB(int id); }; #endif diff --git a/include/qmpcorepublic.hpp b/include/qmpcorepublic.hpp index 7348beb..ad6a165 100644 --- a/include/qmpcorepublic.hpp +++ b/include/qmpcorepublic.hpp @@ -17,10 +17,11 @@ class IMidiCallBack class qmpPluginIntf { public: - virtual void init(); - virtual void deinit(); - virtual const char* pluginGetName(); - virtual const char* pluginGetVersion(); + virtual ~qmpPluginIntf(){} + virtual void init(){} + virtual void deinit(){} + virtual const char* pluginGetName(){return "";} + virtual const char* pluginGetVersion(){return "";} }; class qmpVisualizationIntf { @@ -28,6 +29,7 @@ class qmpVisualizationIntf virtual void show(); virtual void close(); }; +extern "C"{ class qmpPluginAPI { public: @@ -35,15 +37,15 @@ class qmpPluginAPI uint32_t getRawTempo(); double getRealTempo(); uint32_t getTimeSig(); - uint32_t getKeySig(); + int 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 registerEventReaderIntf(IMidiCallBack* cb,void* userdata); + void unregisterEventReaderIntf(int intfhandle); int registerEventHandlerIntf(IMidiCallBack* cb,void* userdata); void unregisterEventHandlerIntf(int intfhandle); void registerOptionInt(std::string desc,std::string key,int defaultval); @@ -53,5 +55,6 @@ class qmpPluginAPI 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/qmpchannelswindow.cpp b/qmidiplayer-desktop/qmpchannelswindow.cpp index 282a4cc..7def34d 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.cpp +++ b/qmidiplayer-desktop/qmpchannelswindow.cpp @@ -17,7 +17,7 @@ qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) : mapper=qmpMainWindow::getInstance()->getPlayer()->getMidiMapper(); cha=new QPixmap(":/img/ledon.png");chi=new QPixmap(":/img/ledoff.png"); cb=new qmpCWNoteOnCB();fused=callbacksc=cbcnt=0; - qmpMainWindow::getInstance()->getPlayer()->setNoteOnCallBack(cb,NULL); + qmpMainWindow::getInstance()->getPlayer()->setEventHandlerCB(cb,NULL); connect(cb,SIGNAL(onNoteOn()),this,SLOT(updateChannelActivity())); int devc=mapper->enumDevices(); //We setup default output here... diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp index 15a53d6..0fa1e06 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.hpp +++ b/qmidiplayer-desktop/qmpchannelswindow.hpp @@ -63,7 +63,8 @@ class qmpCWNoteOnCB:public QObject,public IMidiCallBack { Q_OBJECT public: - void callBack(void*,void*){emit onNoteOn();} + void callBack(void* callerdata,void*) + {if(((((SEventCallBackData*)callerdata)->type)&0xF0)==0x90)emit onNoteOn();} signals: void onNoteOn(); }; diff --git a/qmidiplayer-desktop/qmpinfowindow.cpp b/qmidiplayer-desktop/qmpinfowindow.cpp index 689a756..95ad223 100644 --- a/qmidiplayer-desktop/qmpinfowindow.cpp +++ b/qmidiplayer-desktop/qmpinfowindow.cpp @@ -45,7 +45,7 @@ void qmpInfoWindow::updateInfo() } else ui->lbCopyright->setText(QString("Copyright: ")); ui->lbTempo->setText(QString("Tempo: ")+QString::number(player->getTempo(),'g',5)); - int t,r;player->getCurrentKeySignature(&t);r=(int8_t)((t>>8)&0xFF)+7; + int t,r;t=player->getCurrentKeySignature();r=(int8_t)((t>>8)&0xFF)+7; strncpy(str,t&0xFF?minors+2*r:majors+2*r,2);str[2]='\0'; ui->lbKeySig->setText(QString("Key Sig.: ")+str); player->getCurrentTimeSignature(&t,&r);sprintf(str,"Time Sig.: %d/%d",t,r); diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp index 84697a4..9d73626 100644 --- a/qmidiplayer-desktop/qmpmainwindow.cpp +++ b/qmidiplayer-desktop/qmpmainwindow.cpp @@ -75,6 +75,7 @@ void qmpMainWindow::init() ui->lbFileName->addAction(fnA1); ui->lbFileName->addAction(fnA2); ui->lbFileName->addAction(fnA3); + pmgr->scanPlugins();pmgr->initPlugins(); if(singleFS){player->fluidPreInitialize();playerSetup();player->fluidInitialize(); for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i) LOAD_SOUNDFONT;} diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp index 4da1698..559b575 100644 --- a/qmidiplayer-desktop/qmpplugin.cpp +++ b/qmidiplayer-desktop/qmpplugin.cpp @@ -4,6 +4,7 @@ #include <dlfcn.h> #include <dirent.h> #endif +#include <cstdio> #include <cstring> #include "qmpplugin.hpp" #include "qmpmainwindow.hpp" @@ -53,6 +54,38 @@ qmpPluginManager::~qmpPluginManager() { qmw=NULL;qsw=NULL; } +void qmpPluginManager::initPlugins() +{ + for(unsigned i=0;i<plugins.size();++i) + { + printf("Loaded plugin: %s\n",plugins[i].path.c_str()); + plugins[i].interface->init(); + } +} uint32_t qmpPluginAPI::getDivision() {return qmw->getPlayer()->getDivision();} +uint32_t qmpPluginAPI::getRawTempo() +{return qmw->getPlayer()->getRawTempo();} +double qmpPluginAPI::getRealTempo() +{return qmw->getPlayer()->getTempo();} +uint32_t qmpPluginAPI::getTimeSig() +{int n,d=0,t;qmw->getPlayer()->getCurrentTimeSignature(&n,&t);for(;t>>=1;++d);return n<<8|d;} +int qmpPluginAPI::getKeySig() +{return qmw->getPlayer()->getCurrentKeySignature();} +uint32_t qmpPluginAPI::getNoteCount() +{return qmw->getPlayer()->getFileNoteCount();} +uint32_t qmpPluginAPI::getCurrentPolyphone() +{return qmw->getPlayer()->getPolyphone();} +uint32_t qmpPluginAPI::getMaxPolyphone() +{return qmw->getPlayer()->getMaxPolyphone();} +uint32_t qmpPluginAPI::getCurrentTimeStamp() +{return qmw->getPlayer()->getTCeptr();} +int qmpPluginAPI::registerEventHandlerIntf(IMidiCallBack *cb,void *userdata) +{return qmw->getPlayer()->setEventHandlerCB(cb,userdata);} +void qmpPluginAPI::unregisterEventHandlerIntf(int intfhandle) +{qmw->getPlayer()->unsetEventHandlerCB(intfhandle);} +int qmpPluginAPI::registerEventReaderIntf(IMidiCallBack *cb,void *userdata) +{return qmw->getPlayer()->setEventReaderCB(cb,userdata);} +void qmpPluginAPI::unregisterEventReaderIntf(int intfhandle) +{qmw->getPlayer()->unsetEventReaderCB(intfhandle);} diff --git a/visualization/qmpvisualization.cpp b/visualization/qmpvisualization.cpp new file mode 100644 index 0000000..e8bb9fb --- /dev/null +++ b/visualization/qmpvisualization.cpp @@ -0,0 +1,45 @@ +#include <cstdio> +#include "qmpvisualization.hpp" + +void CTestCallBack::callBack(void *callerdata,void *) +{ + if(par->c<3) + { + SEventCallBackData* cbd=(SEventCallBackData*)callerdata; + printf("type %#x p1 %d p2 %d\n",cbd->type,cbd->p1,cbd->p2); + } +} + +qmpVisualization::qmpVisualization(qmpPluginAPI* _api) +{api=_api;} +qmpVisualization::~qmpVisualization() +{api=NULL;} +void qmpVisualization::init() +{ + puts("hello world from test plugin!"); + puts("I'll try to print the first 3 events from the file!"); + cb=new CTestCallBack(this);c=0; + //!!FIXME: not working properly... + api->registerEventReaderIntf(cb,NULL); +} +void qmpVisualization::deinit() +{} +const char* qmpVisualization::pluginGetName() +{return "QMidiPlayer Default Visualization Plugin";} +const char* qmpVisualization::pluginGetVersion() +{return "0.7.8";} + +//dummy implementations of the api... +uint32_t qmpPluginAPI::getDivision(){return 0;} +uint32_t qmpPluginAPI::getRawTempo(){return 0;} +double qmpPluginAPI::getRealTempo(){return 0;} +uint32_t qmpPluginAPI::getTimeSig(){return 0;} +int qmpPluginAPI::getKeySig(){return 0;} +uint32_t qmpPluginAPI::getNoteCount(){return 0;} +uint32_t qmpPluginAPI::getCurrentPolyphone(){return 0;} +uint32_t qmpPluginAPI::getMaxPolyphone(){return 0;} +uint32_t qmpPluginAPI::getCurrentTimeStamp(){return 0;} +int qmpPluginAPI::registerEventHandlerIntf(IMidiCallBack*,void*){return -1;} +void qmpPluginAPI::unregisterEventHandlerIntf(int){} +int qmpPluginAPI::registerEventReaderIntf(IMidiCallBack*,void*){return -1;} +void qmpPluginAPI::unregisterEventReaderIntf(int){} diff --git a/visualization/qmpvisualization.hpp b/visualization/qmpvisualization.hpp new file mode 100644 index 0000000..847f37b --- /dev/null +++ b/visualization/qmpvisualization.hpp @@ -0,0 +1,36 @@ +#ifndef QMPVISUALIZATION_H +#define QMPVISUALIZATION_H + +#include "../include/qmpcorepublic.hpp" + +class qmpVisualization; +class CTestCallBack:public IMidiCallBack +{ + private: + qmpVisualization *par; + public: + CTestCallBack(qmpVisualization *_par){par=_par;} + void callBack(void *callerdata,void *userdata); +}; +class qmpVisualization:public qmpPluginIntf +{ + friend class CTestCallBack; + private: + qmpPluginAPI* api; + int c; + CTestCallBack* cb; + public: + qmpVisualization(qmpPluginAPI* _api); + ~qmpVisualization(); + void init(); + void deinit(); + const char* pluginGetName(); + const char* pluginGetVersion(); +}; + +extern "C"{ + qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api) + {return new qmpVisualization(api);} +} + +#endif // QMPVISUALIZATION_H diff --git a/visualization/visualization.pro b/visualization/visualization.pro new file mode 100644 index 0000000..8cce718 --- /dev/null +++ b/visualization/visualization.pro @@ -0,0 +1,23 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2016-04-24T22:04:32 +# +#------------------------------------------------- + +QT -= core gui + +CONFIG += c++11 + +TARGET = visualization +TEMPLATE = lib + +DEFINES += VISUALIZATION_LIBRARY + +SOURCES += qmpvisualization.cpp + +HEADERS += qmpvisualization.hpp + +unix { + target.path = /usr/lib/qmidiplayer + INSTALLS += target +} |