From 7b03fd544837fbe0bc5a5373b60dfd5de50892e1 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Sun, 26 May 2019 15:55:28 +0800 Subject: Major code refactor continued and (mostly) concluded. Removed all references to ICallback in official plugins. New flag field in SEvent. Further type usage corrections. --- ChangeLog | 6 ++ core/qmpmidiplay.cpp | 20 ++++-- core/qmpmidiplay.hpp | 2 +- include/qmpcorepublic.hpp | 5 +- qmidiplayer-desktop/qmpchannelswindow.cpp | 21 ++++-- qmidiplayer-desktop/qmpchannelswindow.hpp | 17 ++--- qmidiplayer-desktop/qmpmainwindow.cpp | 3 +- simple-visualization/qmpkeyboardwindow.cpp | 23 +++---- simple-visualization/qmpkeyboardwindow.hpp | 14 +--- visualization/qmpvisualization.cpp | 106 ++++++++++++++--------------- visualization/qmpvisualization.hpp | 32 +-------- 11 files changed, 112 insertions(+), 137 deletions(-) diff --git a/ChangeLog b/ChangeLog index 110602b..65c5997 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2019-05-26 0.8.7 indev +New flag field in SEvent. +Further type usage corrections. +Removed all references to ICallback in official plugins. + 2019-05-25 0.8.7 indev Massive code refactor en cours! Less complain from compilers: @@ -5,6 +10,7 @@ Less complain from compilers: - use types for event fields - explicit type casting added Stop saving parameters of meta events in p1/p2 fields of SEvent. +SEventCallBackData removed. Use SEvent instead. callback_t now uses std::function, deprecating ICallback. 2019-04-22 0.8.7 indev diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp index 1e0cf8c..28ca9e7 100644 --- a/core/qmpmidiplay.cpp +++ b/core/qmpmidiplay.cpp @@ -13,8 +13,12 @@ uint64_t pf; CMidiPlayer* CMidiPlayer::ref=nullptr; bool CMidiPlayer::processEvent(const SEvent *e) { + SEvent fe(*e); + fe.flags&=0xfe; + if(tceptr>=eorder.size()-1||getEvent(tceptr+1)->time>e->time) + fe.flags|=0x01; for(int i=0;i<16;++i)if(eventHandlerCB[i]) - eventHandlerCB[i]->callBack((void*)e,eventHandlerCBuserdata[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); uint8_t ch=e->type&0x0F; @@ -162,7 +166,7 @@ void w32usleep(uint64_t t) timeEndPeriod(1); } #endif -SEvent* CMidiPlayer::getEvent(int id) +SEvent* CMidiPlayer::getEvent(uint32_t id) { size_t t=eorder[id].first,e=eorder[id].second; return &midiFile->tracks[t].eventList[e]; @@ -570,7 +574,9 @@ void CMidiPlayer::unsetFileReadFinishedCB(int id) {fileReadFinishCB[id]=nullptr;fileReadFinishCBuserdata[id]=nullptr;} int CMidiPlayer::registerEventHandler(callback_t cb,void *userdata) { - event_handlers[event_handlers_id++]=std::make_pair(cb,userdata); + int ret; + event_handlers[ret=event_handlers_id++]=std::make_pair(cb,userdata); + return ret; } void CMidiPlayer::unregisterEventHandler(int id) { @@ -578,7 +584,9 @@ void CMidiPlayer::unregisterEventHandler(int id) } int CMidiPlayer::registerEventReadHandler(callback_t cb,void *userdata) { - event_read_handlers[event_read_handlers_id++]=std::make_pair(cb,userdata); + int ret; + event_read_handlers[ret=event_read_handlers_id++]=std::make_pair(cb,userdata); + return ret; } void CMidiPlayer::unregisterEventReadHandler(int id) { @@ -586,7 +594,9 @@ void CMidiPlayer::unregisterEventReadHandler(int id) } int CMidiPlayer::registerFileReadFinishHook(callback_t cb,void *userdata) { - file_read_finish_hooks[file_read_finish_hooks_id++]=std::make_pair(cb,userdata); + int ret; + file_read_finish_hooks[ret=file_read_finish_hooks_id++]=std::make_pair(cb,userdata); + return ret; } void CMidiPlayer::unregisterFileReadFinishHook(int id) { diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp index b94bb08..f42c98b 100644 --- a/core/qmpmidiplay.hpp +++ b/core/qmpmidiplay.hpp @@ -96,7 +96,7 @@ class CMidiPlayer int event_handlers_id,event_read_handlers_id,file_read_finish_hooks_id; static CMidiPlayer* ref; - SEvent *getEvent(int id); + SEvent *getEvent(uint32_t id); void dumpFile(); void setBit(uint16_t &n,uint16_t bn,uint16_t b); bool processEvent(const SEvent *e); diff --git a/include/qmpcorepublic.hpp b/include/qmpcorepublic.hpp index 67a39e0..a4949ac 100644 --- a/include/qmpcorepublic.hpp +++ b/include/qmpcorepublic.hpp @@ -15,12 +15,13 @@ struct SEvent { uint32_t iid,time; uint8_t type,p1,p2; + uint8_t flags; std::string str; - SEvent(){time=p1=p2=0;type=0;str="";} + SEvent(){time=iid=0;type=p1=p2=0;flags=0;str="";} SEvent(uint32_t _iid,uint32_t _t,uint8_t _tp,uint8_t _p1,uint8_t _p2,const char* s=nullptr) { iid=_iid;time=_t;type=_tp; - p1=_p1;p2=_p2; + p1=_p1;p2=_p2;flags=0; if(s)str=std::string(s);else str=""; } friend bool operator <(const SEvent& a,const SEvent& b){return a.time-b.time?a.timegetPlayer()->setEventHandlerCB(cb,nullptr); - connect(cb,SIGNAL(onNoteOn()),this,SLOT(updateChannelActivity())); + fused=callbacksc=cbcnt=0; + eh=qmpMainWindow::getInstance()->getPlayer()->registerEventHandler( + [this](const void *ee,void*){ + const SEvent *e=(const SEvent*)ee; + if((e->type&0xF0)==0x90&&e->p2>0&&(e->flags&0x01)) + emit this->noteOn(); + } + ,nullptr); + connect(this,&qmpChannelsWindow::noteOn,this,&qmpChannelsWindow::updateChannelActivity); std::vector devs=qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices(); size_t devc=devs.size(); //We setup default output here... @@ -131,7 +137,7 @@ void qmpChannelsWindow::channelWindowsUpdate() { for(int i=0;i<16;++i) ui->twChannels->item(i,4)->setText(""); - connect(cb,SIGNAL(onNoteOn()),this,SLOT(updateChannelActivity())); + connect(this,&qmpChannelsWindow::noteOn,this,&qmpChannelsWindow::updateChannelActivity); fused=0;return; } ++cbcnt; @@ -139,7 +145,7 @@ void qmpChannelsWindow::channelWindowsUpdate() { if(callbacksc>8192) { - disconnect(cb,SIGNAL(onNoteOn()),this,SLOT(updateChannelActivity())); + disconnect(this,&qmpChannelsWindow::noteOn,this,&qmpChannelsWindow::updateChannelActivity); fprintf(stderr,"Fuse!\n");fused=1; } cbcnt=0; @@ -156,7 +162,7 @@ void qmpChannelsWindow::channelWindowsUpdate() if(strcmp((ui->twChannels->item(i,4))-> text().toStdString().c_str(),data)) { - connect(cb,SIGNAL(onNoteOn()),this,SLOT(updateChannelActivity())); + connect(this,&qmpChannelsWindow::noteOn,this,&qmpChannelsWindow::updateChannelActivity); fused=0; } } @@ -184,9 +190,10 @@ void qmpChannelsWindow::channelMSChanged() qmpChannelsWindow::~qmpChannelsWindow() { qmpMainWindow::getInstance()->unregisterFunctionality("Channel"); + qmpMainWindow::getInstance()->getPlayer()->unregisterEventHandler(eh); delete chnlf; delete chi;delete cha; - delete cb;delete ui; + delete ui; } void qmpChannelsWindow::on_pbUnmute_clicked() diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp index 36cba3c..207ee8d 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.hpp +++ b/qmidiplayer-desktop/qmpchannelswindow.hpp @@ -48,16 +48,6 @@ class QDCComboBox:public QComboBox void indexChangedSlot(int idx){emit(onChange(id,idx));} }; -class qmpCWNoteOnCB:public QObject,public ICallBack -{ - Q_OBJECT - public: - void callBack(const void* callerdata,void*) - {if(((((const SEvent*)callerdata)->type)&0xF0)==0x90)emit onNoteOn();} - signals: - void onNoteOn(); -}; - class qmpChannelsWindow; class qmpChannelFunc:public qmpFuncBaseIntf @@ -75,7 +65,7 @@ class qmpChannelsWindow:public QWidget Q_OBJECT public: - explicit qmpChannelsWindow(QWidget *parent=0); + explicit qmpChannelsWindow(QWidget *parent=nullptr); ~qmpChannelsWindow(); void showEvent(QShowEvent *event); void closeEvent(QCloseEvent *event); @@ -90,6 +80,9 @@ class qmpChannelsWindow:public QWidget void on_pbUnmute_clicked(); void on_pbUnsolo_clicked(); + signals: + void noteOn(); + protected: bool eventFilter(QObject *o,QEvent *e); @@ -98,8 +91,8 @@ class qmpChannelsWindow:public QWidget qmpPresetSelector *pselectw; qmpChannelEditor *ceditw; QIcon *cha,*chi; - qmpCWNoteOnCB *cb; qmpChannelFunc *chnlf; + int eh; //callback fuse... (avoid black midi blocking the main thread) int callbacksc,cbcnt,fused; }; diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp index 5f9dfba..cd00b2e 100644 --- a/qmidiplayer-desktop/qmpmainwindow.cpp +++ b/qmidiplayer-desktop/qmpmainwindow.cpp @@ -54,7 +54,7 @@ qmpMainWindow::~qmpMainWindow() std::vector> rtdev=rtmididev->getDevices(); for(auto &i:rtdev)player->unregisterMidiOutDevice(i.second); rtmididev->deleteDevices(); - delete pmgr;if(player)delete player; + delete pmgr; if(timer)delete timer; delete helpw;helpw=nullptr; delete efxw;efxw=nullptr; @@ -65,6 +65,7 @@ qmpMainWindow::~qmpMainWindow() delete panicf;panicf=nullptr; delete renderf;renderf=nullptr; delete reloadsynf;reloadsynf=nullptr; + if(player)delete player; delete ui; } diff --git a/simple-visualization/qmpkeyboardwindow.cpp b/simple-visualization/qmpkeyboardwindow.cpp index f2cc8b7..562596c 100644 --- a/simple-visualization/qmpkeyboardwindow.cpp +++ b/simple-visualization/qmpkeyboardwindow.cpp @@ -9,11 +9,20 @@ qmpKeyboardWindow::qmpKeyboardWindow(qmpPluginAPI *_api,QWidget *parent): for(int ch=0;ch<16;++ch) layout()->addWidget(pw[ch]=new qmpPianoWidget(this)); hide(); - api->registerEventHandlerIntf(ec=new EventCallback(),this); - connect(ec,&EventCallback::keystateupdated,this,&qmpKeyboardWindow::onkeystatesupdate); + eh=api->registerEventHandler( + [this](const void* ee,void*){ + const SEvent *e=(const SEvent*)ee; + if((e->type&0xF0)==0x80||((e->type&0xF0)==0x90&&e->p2==0)) + emit keystateupdated(e->type&0xF,e->p1,false); + if((e->type&0xF0)==0x90&&e->p2>0) + emit keystateupdated(e->type&0xF,e->p1,e->p2>0); + } + ,nullptr); + connect(this,&qmpKeyboardWindow::keystateupdated,this,&qmpKeyboardWindow::onkeystatesupdate); } qmpKeyboardWindow::~qmpKeyboardWindow() { + api->unregisterEventHandler(eh); } void qmpKeyboardWindow::closeEvent(QCloseEvent *event) { @@ -24,13 +33,3 @@ 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();} - -void EventCallback::callBack(const void *callerdata,void* userdata) -{ - const qmpKeyboardWindow *w=(const qmpKeyboardWindow*)userdata; - const SEvent *cbd=(const SEvent*)callerdata; - if((cbd->type&0xF0)==0x80) - emit keystateupdated(cbd->type&0xF,cbd->p1,false); - if((cbd->type&0xF0)==0x90) - emit keystateupdated(cbd->type&0xF,cbd->p1,cbd->p2>0); -} diff --git a/simple-visualization/qmpkeyboardwindow.hpp b/simple-visualization/qmpkeyboardwindow.hpp index 2b618fa..563b6b4 100644 --- a/simple-visualization/qmpkeyboardwindow.hpp +++ b/simple-visualization/qmpkeyboardwindow.hpp @@ -6,29 +6,21 @@ #include -class EventCallback:public QObject,public ICallBack -{ - Q_OBJECT - public: - void callBack(const void *callerdata,void *userdata); - signals: - void keystateupdated(int ch,int key,bool state); -}; - class qmpKeyboardWindow:public QWidget { Q_OBJECT - friend class EventCallback; private: qmpPianoWidget *pw[16]; qmpPluginAPI *api; - EventCallback *ec; + int eh; public: qmpKeyboardWindow(qmpPluginAPI *_api,QWidget *parent); ~qmpKeyboardWindow(); void resetAll(); protected: void closeEvent(QCloseEvent *event); + signals: + void keystateupdated(int ch,int key,bool state); public slots: void onkeystatesupdate(int ch,int key,bool state); }; diff --git a/visualization/qmpvisualization.cpp b/visualization/qmpvisualization.cpp index c8dbcff..6d4acf4 100644 --- a/visualization/qmpvisualization.cpp +++ b/visualization/qmpvisualization.cpp @@ -41,51 +41,6 @@ bool cmp(MidiVisualEvent* a,MidiVisualEvent* b) if(a->tcstcs)return true;if(a->tcs>b->tcs)return false; if(a->tcetce)return true;return false; } -void CReaderCallBack::callBack(const void *callerdata,void *) -{ - const SEvent* cbd=(const SEvent*)callerdata; - switch(cbd->type&0xF0) - { - case 0x80: - par->pushNoteOff(cbd->time,cbd->type&0x0F,cbd->p1); - break; - case 0x90: - if(cbd->p2) - par->pushNoteOn(cbd->time,cbd->type&0x0F,cbd->p1,cbd->p2); - else - par->pushNoteOff(cbd->time,cbd->type&0x0F,cbd->p1); - break; - case 0xF0: - if(cbd->type==0xFF&&cbd->p1==0x58) - par->tspool.push_back(std::make_pair(cbd->time,(cbd->str[0]<<24)|(cbd->str[1]<<16))); - break; - } -} -void CEventHandlerCallBack::callBack(const void*,void*) -{ - if(par->ctk>par->api->getCurrentTimeStamp()+par->api->getDivision()/3) - par->elb=0; - /*if(abs((int)par->ctk-(int)par->api->getCurrentTimeStamp())>par->api->getDivision()/4) - fprintf(stderr,"Visualization: out of sync! %u vs %u ad: %u\n",par->ctk,par->api->getCurrentTimeStamp());*/ - par->ctk=par->api->getCurrentTimeStamp(); -} -void CFRFinishedCallBack::callBack(const void*,void*) -{ - std::sort(par->tspool.begin(),par->tspool.end()); - for(uint32_t tk=0,n=4,s=0;tk<=par->api->getMaxTick();){ - while(tk<(s>=par->tspool.size()?par->api->getMaxTick():par->tspool[s].first)){ - par->pool.push_back(new MidiVisualEvent{tk,tk,0,0,999}); - tk+=n*par->api->getDivision(); - } - tk=(s>=par->tspool.size()?par->api->getMaxTick():par->tspool[s].first); - if(tk==par->api->getMaxTick()){ - par->pool.push_back(new MidiVisualEvent{tk,tk,0,0,999}); - ++tk;break; - } - else n=par->tspool[s++].second>>24; - } - std::sort(par->pool.begin(),par->pool.end(),cmp); -} void qmpVisualization::showThread() { wwidth=api->getOptionInt("Visualization/wwidth"); @@ -749,10 +704,7 @@ qmpVisualization::qmpVisualization(qmpPluginAPI* _api){api=_api;} qmpVisualization::~qmpVisualization(){api=nullptr;} void qmpVisualization::init() { - cb=new CReaderCallBack(this); - hcb=new CEventHandlerCallBack(this); h=new CMidiVisualHandler(this); - frcb=new CFRFinishedCallBack(this); closeh=new CloseHandler(this); rendererTh=nullptr;playing=false; memset(spectra,0,sizeof(spectra)); @@ -762,9 +714,54 @@ void qmpVisualization::init() uihs=api->registerUIHook("main.stop",[this](const void*,void*){this->stop();},nullptr); uihp=api->registerUIHook("main.pause",[this](const void*,void*){this->pause();},nullptr); uihr=api->registerUIHook("main.reset",[this](const void*,void*){this->reset();},nullptr); - herif=api->registerEventReaderIntf(cb,nullptr); - hehif=api->registerEventHandlerIntf(hcb,nullptr); - hfrf=api->registerFileReadFinishedHandlerIntf(frcb,nullptr); + herh=api->registerEventReadHandler( + [this](const void *ee,void*){ + const SEvent* e=(const SEvent*)ee; + switch(e->type&0xF0) + { + case 0x80: + this->pushNoteOff(e->time,e->type&0x0F,e->p1); + break; + case 0x90: + if(e->p2) + this->pushNoteOn(e->time,e->type&0x0F,e->p1,e->p2); + else + this->pushNoteOff(e->time,e->type&0x0F,e->p1); + break; + case 0xF0: + if(e->type==0xFF&&e->p1==0x58) + this->tspool.push_back(std::make_pair(e->time,(e->str[0]<<24)|(e->str[1]<<16))); + break; + } + } + ,nullptr); + heh=api->registerEventHandler( + [this](const void*,void*){ + if(this->ctk>this->api->getCurrentTimeStamp()+this->api->getDivision()/3) + this->elb=0; + /*if(abs((int)this->ctk-(int)this->api->getCurrentTimeStamp())>this->api->getDivision()/4) + fprintf(stderr,"Visualization: out of sync! %u vs %u ad: %u\n",this->ctk,this->api->getCurrentTimeStamp());*/ + this->ctk=this->api->getCurrentTimeStamp(); + } + ,nullptr); + hfrf=api->registerFileReadFinishHook( + [this](const void*,void*){ + std::sort(this->tspool.begin(),this->tspool.end()); + for(uint32_t tk=0,n=4,s=0;tk<=this->api->getMaxTick();){ + while(tk<(s>=this->tspool.size()?this->api->getMaxTick():this->tspool[s].first)){ + this->pool.push_back(new MidiVisualEvent{tk,tk,0,0,999}); + tk+=n*this->api->getDivision(); + } + tk=(s>=this->tspool.size()?this->api->getMaxTick():this->tspool[s].first); + if(tk==this->api->getMaxTick()){ + this->pool.push_back(new MidiVisualEvent{tk,tk,0,0,999}); + ++tk;break; + } + else n=this->tspool[s++].second>>24; + } + std::sort(this->pool.begin(),this->pool.end(),cmp); + } + ,nullptr); api->registerOptionBool("Visualization-Appearance","Show Piano","Visualization/showpiano",true); api->registerOptionBool("Visualization-Appearance","3D Notes","Visualization/3dnotes",true); api->registerOptionBool("Visualization-Appearance","Arrange channels on a stair","Visualization/stairpiano",true); @@ -840,10 +837,9 @@ void qmpVisualization::deinit() api->unregisterUIHook("main.pause",uihp); api->unregisterUIHook("main.reset",uihr); api->unregisterFunctionality("Visualization"); - api->unregisterEventReaderIntf(herif); - api->unregisterEventHandlerIntf(hehif); - api->unregisterFileReadFinishedHandlerIntf(hfrf); - delete cb;delete hcb;delete frcb; + api->unregisterEventReadHandler(herh); + api->unregisterEventHandler(heh); + api->unregisterFileReadFinishHook(hfrf); delete h;delete closeh; } const char* qmpVisualization::pluginGetName() diff --git a/visualization/qmpvisualization.hpp b/visualization/qmpvisualization.hpp index 4e0412b..4aaeb0c 100644 --- a/visualization/qmpvisualization.hpp +++ b/visualization/qmpvisualization.hpp @@ -12,30 +12,6 @@ #include "../include/qmpcorepublic.hpp" class qmpVisualization; -class CReaderCallBack:public ICallBack -{ - private: - qmpVisualization *par; - public: - CReaderCallBack(qmpVisualization *_par){par=_par;} - void callBack(const void *callerdata,void *userdata); -}; -class CEventHandlerCallBack:public ICallBack -{ - private: - qmpVisualization *par; - public: - CEventHandlerCallBack(qmpVisualization *_par){par=_par;} - void callBack(const void*,void*); -}; -class CFRFinishedCallBack:public ICallBack -{ - private: - qmpVisualization *par; - public: - CFRFinishedCallBack(qmpVisualization *_par){par=_par;} - void callBack(const void*,void*); -}; struct MidiVisualEvent { uint32_t tcs,tce; @@ -44,15 +20,9 @@ struct MidiVisualEvent }; class qmpVisualization:public qmpPluginIntf,public qmpFuncBaseIntf { - friend class CEventHandlerCallBack; - friend class CReaderCallBack; friend class CloseHandler; - friend class CFRFinishedCallBack; private: qmpPluginAPI* api; - CReaderCallBack* cb; - CEventHandlerCallBack* hcb; - CFRFinishedCallBack* frcb; std::thread* rendererTh; std::vectorpool; smHandler *h,*closeh; @@ -69,7 +39,7 @@ class qmpVisualization:public qmpPluginIntf,public qmpFuncBaseIntf uint32_t ctc,ctk,elb; double etps; bool shouldclose,playing; - int herif,hehif,hfrf; + int herh,heh,hfrf; int uihb,uihs,uihp,uihr; std::vector>tspool; int traveld[16][128];bool notestatus[16][128],lastnotestatus[16][128]; -- cgit v1.2.3