aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2019-11-02 22:13:32 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2019-11-02 22:13:32 +0800
commitb2ef363f49db70219ac1eaebb7d69dcdade8d60b (patch)
treecfc0e8da88dc27b62578dccbce367736e020f63d
parent23525e2a648a23f099c2b533aa91839a2f8e829f (diff)
downloadQMidiPlayer-b2ef363f49db70219ac1eaebb7d69dcdade8d60b.tar.xz
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.
-rw-r--r--core/qmpmidiplay.cpp12
-rw-r--r--core/qmpmidiplay.hpp5
-rw-r--r--include/qmpcorepublic.hpp2
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.cpp4
-rw-r--r--qmidiplayer-desktop/qmpplugin.cpp12
-rw-r--r--simple-visualization/qmpkeyboardwindow.cpp42
-rw-r--r--simple-visualization/qmpkeyboardwindow.hpp4
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&&tceptr<ecnt&&ct==getEvent(tceptr)->time;++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 <cstdlib>
#include <chrono>
#include <unordered_map>
+#include <tuple>
#include <utility>
#include <vector>
#define QMP_MAIN
@@ -91,7 +92,7 @@ class CMidiPlayer
void* eventHandlerCBuserdata[16];
void* eventReaderCBuserdata[16];
void* fileReadFinishCBuserdata[16];
- std::unordered_map<int,std::pair<callback_t,void*>> event_handlers;
+ std::unordered_map<int,std::tuple<callback_t,void*,bool>> event_handlers;
std::unordered_map<int,std::pair<callback_t,void*>> event_read_handlers;
std::unordered_map<int,std::pair<callback_t,void*>> 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<std::string> devs=qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices();
size_t devc=devs.size();
std::set<std::string> 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 <QVBoxLayout>
+#include <QGridLayout>
#include <QCloseEvent>
+#include <QLabel>
+#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 <QWidget>
+class QLabel;
+class qmpPianoWidget;
class qmpKeyboardWindow:public QWidget
{
Q_OBJECT
private:
qmpPianoWidget *pw[16];
+ QLabel *lb[16];
qmpPluginAPI *api;
int eh;
public: