From b2ef363f49db70219ac1eaebb7d69dcdade8d60b Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Sat, 2 Nov 2019 22:13:32 +0800 Subject: Keyboard plugin: show additional information on the side. qmpPluginAPI::registerEventHandler now accepts an optional argument that determines whether the handler is called prior to or after an event is sent. --- core/qmpmidiplay.cpp | 12 ++++++--- core/qmpmidiplay.hpp | 5 ++-- include/qmpcorepublic.hpp | 2 +- qmidiplayer-desktop/qmpchannelswindow.cpp | 4 +-- qmidiplayer-desktop/qmpplugin.cpp | 12 ++++++--- simple-visualization/qmpkeyboardwindow.cpp | 42 +++++++++++++++++++++++++----- simple-visualization/qmpkeyboardwindow.hpp | 4 ++- 7 files changed, 63 insertions(+), 18 deletions(-) diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp index 46a2dae..2992e06 100644 --- a/core/qmpmidiplay.cpp +++ b/core/qmpmidiplay.cpp @@ -20,7 +20,8 @@ bool CMidiPlayer::processEvent(const SEvent *e) for(int i=0;i<16;++i)if(eventHandlerCB[i]) eventHandlerCB[i]->callBack((void*)&fe,eventHandlerCBuserdata[i]); for(auto i=event_handlers.begin();i!=event_handlers.end();++i) - i->second.first((void*)e,i->second.second); + if(!std::get<2>(i->second)) + std::get<0>(i->second)((void*)e,std::get<1>(i->second)); uint8_t ch=e->type&0x0F; if((e->type&0xF0)<0xF0) levtt[ch]=std::chrono::system_clock::now(); @@ -195,11 +196,16 @@ void CMidiPlayer::playEvents() //fprintf(stderr,"@ tick %u, dtime %.6fus",getTick(),_dt/1000.); } for(;!tcstop&&midiReaders&&tceptrtime;++tceptr) + { if(processEvent(getEvent(tceptr))) { SEvent* e=getEvent(tceptr); mididev[mappedoutput[e->type&0x0F]].dev->basicMessage(e->type,e->p1,e->p2); } + for(auto i=event_handlers.begin();i!=event_handlers.end();++i) + if(std::get<2>(i->second)) + std::get<0>(i->second)((void*)getEvent(tceptr),std::get<1>(i->second)); + } if(tcstop||!midiReaders||tceptr>=ecnt)break; high_resolution_clock::time_point a=high_resolution_clock::now(); auto sendtime=a-b; @@ -553,10 +559,10 @@ int CMidiPlayer::setFileReadFinishedCB(ICallBack *cb,void *userdata) } void CMidiPlayer::unsetFileReadFinishedCB(int id) {fileReadFinishCB[id]=nullptr;fileReadFinishCBuserdata[id]=nullptr;} -int CMidiPlayer::registerEventHandler(callback_t cb,void *userdata) +int CMidiPlayer::registerEventHandler(callback_t cb,void *userdata,bool post) { int ret; - event_handlers[ret=event_handlers_id++]=std::make_pair(cb,userdata); + event_handlers[ret=event_handlers_id++]=std::make_tuple(cb,userdata,post); return ret; } void CMidiPlayer::unregisterEventHandler(int id) diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp index 4d950fa..c3833a5 100644 --- a/core/qmpmidiplay.hpp +++ b/core/qmpmidiplay.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #define QMP_MAIN @@ -91,7 +92,7 @@ class CMidiPlayer void* eventHandlerCBuserdata[16]; void* eventReaderCBuserdata[16]; void* fileReadFinishCBuserdata[16]; - std::unordered_map> event_handlers; + std::unordered_map> event_handlers; std::unordered_map> event_read_handlers; std::unordered_map> file_read_finish_hooks; int event_handlers_id,event_read_handlers_id,file_read_finish_hooks_id; @@ -163,7 +164,7 @@ class CMidiPlayer void unsetEventReaderCB(int id); int setFileReadFinishedCB(ICallBack *cb,void *userdata); void unsetFileReadFinishedCB(int id); - int registerEventHandler(callback_t cb,void *userdata); + int registerEventHandler(callback_t cb,void *userdata,bool post); void unregisterEventHandler(int id); int registerEventReadHandler(callback_t cb,void *userdata); void unregisterEventReadHandler(int id); diff --git a/include/qmpcorepublic.hpp b/include/qmpcorepublic.hpp index 178fa19..35a7a70 100644 --- a/include/qmpcorepublic.hpp +++ b/include/qmpcorepublic.hpp @@ -169,7 +169,7 @@ class qmpPluginAPI virtual void unregisterEventHandlerIntf(int intfhandle); virtual int registerFileReadFinishedHandlerIntf(ICallBack* cb,void* userdata); virtual void unregisterFileReadFinishedHandlerIntf(int intfhandle); - virtual int registerEventHandler(callback_t cb,void *userdata); + virtual int registerEventHandler(callback_t cb,void *userdata,bool post=false); virtual void unregisterEventHandler(int id); virtual int registerEventReadHandler(callback_t cb,void *userdata); virtual void unregisterEventReadHandler(int id); diff --git a/qmidiplayer-desktop/qmpchannelswindow.cpp b/qmidiplayer-desktop/qmpchannelswindow.cpp index 13f2c8d..41f545e 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.cpp +++ b/qmidiplayer-desktop/qmpchannelswindow.cpp @@ -22,7 +22,7 @@ qmpChannelsModel::qmpChannelsModel(QObject*parent):QAbstractTableModel(parent) QMetaObject::invokeMethod(this, &qmpChannelsModel::updateChannelActivity, Qt::ConnectionType::QueuedConnection); } } - ,nullptr); + ,nullptr,false); QTimer*t=new QTimer(this); t->setInterval(500); t->setSingleShot(false); @@ -267,7 +267,7 @@ qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) : if((e->type&0xF0)==0x90&&e->p2>0&&(e->flags&0x01)) emit this->noteOn(); } - ,nullptr); + ,nullptr,false); std::vector devs=qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices(); size_t devc=devs.size(); std::set devset; diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp index fd79b16..774f0da 100644 --- a/qmidiplayer-desktop/qmpplugin.cpp +++ b/qmidiplayer-desktop/qmpplugin.cpp @@ -179,7 +179,13 @@ std::string qmpPluginAPI::getChannelPresetString(int ch) std::string nm; if(qmw&&qmw->getPlayer()) { - qmw->getPlayer()->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,nm); + int r=qmw->getPlayer()->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,nm); + if(!r) + { + b=qmw->getPlayer()->getCC(ch,0)<<7|qmw->getPlayer()->getCC(ch,32); + p=qmw->getPlayer()->getCC(ch,128); + nm=qmw->getPlayer()->getChannelOutputDevice(ch)->getPresetName(b,p); + } snprintf(ret,320,"%03d:%03d %s",b,p,nm.c_str()); } return std::string(ret); @@ -223,8 +229,8 @@ void qmpPluginAPI::registerFileReader(qmpFileReader* reader,std::string name) {qmw->getPlayer()->registerReader(reader,name);} void qmpPluginAPI::unregisterFileReader(std::string name) {qmw->getPlayer()->unregisterReader(name);} -int qmpPluginAPI::registerEventHandler(callback_t cb,void *userdata) -{return qmw->getPlayer()->registerEventHandler(cb,userdata);} +int qmpPluginAPI::registerEventHandler(callback_t cb,void *userdata,bool post) +{return qmw->getPlayer()->registerEventHandler(cb,userdata,post);} void qmpPluginAPI::unregisterEventHandler(int id) {qmw->getPlayer()->unregisterEventHandler(id);} int qmpPluginAPI::registerEventReadHandler(callback_t cb,void *userdata) diff --git a/simple-visualization/qmpkeyboardwindow.cpp b/simple-visualization/qmpkeyboardwindow.cpp index 562596c..8fe0e6f 100644 --- a/simple-visualization/qmpkeyboardwindow.cpp +++ b/simple-visualization/qmpkeyboardwindow.cpp @@ -1,23 +1,41 @@ #include +#include #include +#include +#include "qmppianowidget.hpp" #include "qmpkeyboardwindow.hpp" qmpKeyboardWindow::qmpKeyboardWindow(qmpPluginAPI *_api,QWidget *parent): QWidget(parent,Qt::Dialog),api(_api) { - setLayout(new QVBoxLayout()); + setWindowTitle("Keyboard"); + QGridLayout *grid; + setLayout(grid=new QGridLayout()); for(int ch=0;ch<16;++ch) - layout()->addWidget(pw[ch]=new qmpPianoWidget(this)); + { + grid->addWidget(lb[ch]=new QLabel,ch,0); + grid->addWidget(pw[ch]=new qmpPianoWidget(this),ch,1); + pw[ch]->setSizePolicy(QSizePolicy::Policy::Expanding,QSizePolicy::Policy::Preferred); + } hide(); eh=api->registerEventHandler( [this](const void* ee,void*){ const SEvent *e=(const SEvent*)ee; + int ch=e->type&0xF; if((e->type&0xF0)==0x80||((e->type&0xF0)==0x90&&e->p2==0)) - emit keystateupdated(e->type&0xF,e->p1,false); + emit keystateupdated(ch,e->p1,false); if((e->type&0xF0)==0x90&&e->p2>0) - emit keystateupdated(e->type&0xF,e->p1,e->p2>0); + emit keystateupdated(ch,e->p1,e->p2>0); + if((e->type&0xF0)==0xB0||(e->type&0xF0)==0xC0) + lb[ch]->setText( + QString::fromStdString(api->getChannelPresetString(ch))+ + QString("\nch:%1 v:%2 p:%3 e:%4") + .arg(QString::number(ch+1)) + .arg(QString::number(api->getChannelCC(ch,0x7))) + .arg(QString::number(api->getChannelCC(ch,0xa))) + .arg(QString::number(api->getChannelCC(ch,0xb)))); } - ,nullptr); + ,nullptr,true); connect(this,&qmpKeyboardWindow::keystateupdated,this,&qmpKeyboardWindow::onkeystatesupdate); } qmpKeyboardWindow::~qmpKeyboardWindow() @@ -32,4 +50,16 @@ void qmpKeyboardWindow::closeEvent(QCloseEvent *event) void qmpKeyboardWindow::onkeystatesupdate(int ch,int key,bool state) {pw[ch]->setKeyState(key,state);} void qmpKeyboardWindow::resetAll() -{for(int ch=0;ch<16;++ch)pw[ch]->reset();} +{ + for(int ch=0;ch<16;++ch) + { + pw[ch]->reset(); + lb[ch]->setText( + QString::fromStdString(api->getChannelPresetString(ch))+ + QString("\nch:%1 v:%2 p:%3 e:%4") + .arg(QString::number(ch+1)) + .arg(QString::number(api->getChannelCC(ch,0x7))) + .arg(QString::number(api->getChannelCC(ch,0xa))) + .arg(QString::number(api->getChannelCC(ch,0xb)))); + } +} diff --git a/simple-visualization/qmpkeyboardwindow.hpp b/simple-visualization/qmpkeyboardwindow.hpp index 563b6b4..65ad266 100644 --- a/simple-visualization/qmpkeyboardwindow.hpp +++ b/simple-visualization/qmpkeyboardwindow.hpp @@ -2,15 +2,17 @@ #define QMPKEYBOARDWINDOW_HPP #include "../include/qmpcorepublic.hpp" -#include "qmppianowidget.hpp" #include +class QLabel; +class qmpPianoWidget; class qmpKeyboardWindow:public QWidget { Q_OBJECT private: qmpPianoWidget *pw[16]; + QLabel *lb[16]; qmpPluginAPI *api; int eh; public: -- cgit v1.2.3